Given the following Eiffel classes:
class A feature f is do ... end end class B inherit A redefine f end feature f is do ... end end
You will get the following pseudo-CIL code:
.class public auto ansi A extends [mscorlib]System.Object { .method public virtual instance void f() cil managed { // ... } } .class public auto ansi B extends A { .method public virtual instance void f() cil managed { // ... } }
Given the following Eiffel classes and supposing that class Y inherits from class X:
class A feature f (x: X) is do ... end end class B inherit A redefine f end feature f (y: Y) is do ... end end
You will get the following pseudo-CIL code:
.class public auto ansi A extends [mscorlib]System.Object { .method public virtual instance void f([in] class X x) cil managed { // ... } } .class public auto ansi B extends A { .method public virtual instance void f([in] class Y y) cil managed { // ... } .method private final virtual instance void __f(class X A_1) cil managed { .override A::f // Code size 13 (0xd) .maxstack 2 IL_0000: ldarg.0 IL_0001: ldarg.1 IL_0002: castclass Y IL_0007: callvirt instance void B::f(class Y) IL_000c: ret } }
Note the `castclass' that is needed to dynamically check the type of the routine. When generating verifiable code it will always be present, otherwise it is useless to generate the cast since we are 99% sure that the argument will have the correct type (in this case Y).
Given the following Eiffel classes:
class A feature f is do ... end end class B inherit A rename f as g end end
You will get the following pseudo-CIL code:
.class public auto ansi A extends [mscorlib]System.Object { .method public virtual instance void f() cil managed { // ... } } .class public auto ansi B extends A { .method public virtual instance void g() cil managed { .override A::f // Code size 7 (0x7) .maxstack 1 IL_0000: ldarg.0 IL_0001: call instance int32 A::f() IL_0006: ret } }
Given the following Eiffel classes:
class A feature f: INTEGER end class B inherit A rename f as g end end
You will get the following pseudo-CIL code:
.class public auto ansi A extends [mscorlib]System.Object { .field assembly int32 _internal_f .method public specialname virtual instance int32 get_f() cil managed { .maxstack 1 IL_0000: ldarg.0 IL_0001: ldfld int32 A::_internal_f IL_0006: ret } .property int32 f() { .get instance int32 A::get_f() } } .class public auto ansi B extends A { .method public virtual instance void get_g() cil managed { .override A::get_f // Code size 7 (0x7) .maxstack 1 IL_0000: ldarg.0 IL_0001: call instance int32 A::get_f() IL_0006: ret } .property int32 g() { .get instance int32 B::get_g() } }
Given the following Eiffel classes:
class A feature f is do ... end end class B inherit A rename f as g end feature f is do ... end end
You will get the following pseudo-CIL code:
.class public auto ansi A extends [mscorlib]System.Object { .method public virtual instance void f() cil managed { // ... } } .class public auto ansi B extends A { .method public virtual instance void f() cil managed { // ... } .method public virtual instance void g() cil managed { .override A::f // Code size 7 (0x7) .maxstack 1 IL_0000: ldarg.0 IL_0001: call instance int32 A::f() IL_0006: ret } }
Given the following Eiffel classes:
class A feature frozen f is do ... end end class B inherit A rename f as g end end
You will get the following pseudo-CIL code:
.class public auto ansi A extends [mscorlib]System.Object { .method public final virtual instance void f() cil managed { // ... } } .class public auto ansi B extends A { .method public final virtual instance void g() cil managed { // Code size 7 (0x7) .maxstack 2 IL_0000: ldarg.0 IL_0001: call instance void A::f() IL_0006: ret } }
In the case of B, both `f' and `g' are available in .NET and only `g' is available in Eiffel. It is not correct, but it is not harmful.
Given the following Eiffel classes:
class A feature frozen f is do ... end end class B inherit A rename f as g end end
You will get the following pseudo-CIL code:
.class public auto ansi A extends [mscorlib]System.Object { .method public final virtual instance void f() cil managed { // ... } } .class public auto ansi B extends A { .method public final virtual instance void g() cil managed { // Code size 7 (0x7) .maxstack 2 IL_0000: ldarg.0 IL_0001: call instance void A::f() IL_0006: ret } }
In the case of B, both `f' and `g' are available in .NET and only `g' is available in Eiffel. It is not correct, but it is not harmful.
Given the following Eiffel classes:
class A feature f is do ... end end class B inherit A rename f as g redefine g end feature g is do ... end end
You will get the following pseudo-CIL code:
.class public auto ansi A extends [mscorlib]System.Object { .method public virtual instance void f() cil managed { // ... } } .class public auto ansi B extends A { .method private final virtual instance void g() cil managed { .override A::f // .... } }
Given the following Eiffel classes:
class A feature f (x: X) is do ... end end class B inherit A rename f as g redefine g end feature g (y: Y) is do ... end end
You will get the following pseudo-CIL code:
.class public auto ansi A extends [mscorlib]System.Object { .method public virtual instance void f([in] class X x) cil managed { // ... } } .class public auto ansi B extends A { .method public virtual instance void g([in] class Y y) cil managed { // ... } .method private final virtual instance void __g(class X A_1) cil managed { .override A::f // Code size 13 (0xd) .maxstack 2 IL_0000: ldarg.0 IL_0001: ldarg.1 IL_0002: castclass Y IL_0007: callvirt instance void B::g(class Y) IL_000c: ret } }
Because attributes are generated as .NET field that are only accessible from an assembly, we had to generate a .NET property counter part that can be accessed from other assemblies.\
In doing so we introduced a .NET getter method to access the attribute. Since it is a .NET method, we can apply it all the previous rules we have seen to achieve: