/* polymorphic linked lists with a mixture of generics and inheritance */ using System; // want: linked list with both natural and ad-hoc polymorphic functions public interface addable { T add(T other); } public class integer : addable { internal int x; // internal means public within same assembly public integer(int y) {x=y;} // constructor public integer add(integer other) { return new integer(other.x+x); } public override string ToString() { return ""+x; } } public class rational : addable { internal int n, d; // numerator and denominator public rational(int a, int b) { n=a; d=b; } public rational add(rational R) { int sd = R.d * d; int sn = n*R.d + R.n*d; return new rational(sn,sd); } public override string ToString() { return n+"/"+d; } } // polymorphic linked list class public class cell where T : addable { internal T car; internal cell cdr; public cell(T a, cell b) {car=a; cdr=b;} // constructor // naturally polymorphic function: public int length() { int ax = 0; for(cell i=this; i!=null; i=i.cdr) ax++; return ax; } // ad-hoc polymorphic function public T sum() { T ax = car; for(cell i=cdr; i!=null; i=i.cdr) ax = ax.add(i.car); return ax; } }// cell public class polylists { public static void Main() { cell ilist = new cell(new integer(3),null); cell rlist = new cell(new rational(1,4),null); Console.WriteLine(ilist.length()); Console.WriteLine(rlist.length()); } } // compile to .exe with (csc) mcs polylists.cs // disassemble into .Net IL with: monodis polylists.exe /* generated .Net intermediate language (.Net byte code) ==================================================================== .assembly extern mscorlib { .ver 4:0:0:0 .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. } .assembly 'polylists' { .custom instance void class [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::'.ctor'() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx 63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows. .hash algorithm 0x00008004 .ver 0:0:0:0 } .module polylists.exe // GUID = {C7B6D94A-2CCE-47C4-8815-D7F509240D75} .class interface public auto ansi abstract addable`1 { // method line 1 .method public virtual hidebysig newslot abstract instance default !T 'add' (!T other) cil managed { // Method begins at RVA 0x0 } // end of method addable`1::add } // end of class addable`1 .class public auto ansi beforefieldinit integer extends [mscorlib]System.Object implements class addable`1 { .field assembly int32 x // method line 2 .method public hidebysig specialname rtspecialname instance default void '.ctor' (int32 y) cil managed { // Method begins at RVA 0x2050 // Code size 14 (0xe) .maxstack 8 IL_0000: ldarg.0 IL_0001: call instance void object::'.ctor'() IL_0006: ldarg.0 IL_0007: ldarg.1 IL_0008: stfld int32 integer::x IL_000d: ret } // end of method integer::.ctor // method line 3 .method public final virtual hidebysig newslot instance default class integer 'add' (class integer other) cil managed { // Method begins at RVA 0x205f // Code size 19 (0x13) .maxstack 8 IL_0000: ldarg.1 IL_0001: ldfld int32 integer::x IL_0006: ldarg.0 IL_0007: ldfld int32 integer::x IL_000c: add IL_000d: newobj instance void class integer::'.ctor'(int32) IL_0012: ret } // end of method integer::add // method line 4 .method public virtual hidebysig instance default string ToString () cil managed { // Method begins at RVA 0x2073 // Code size 22 (0x16) .maxstack 8 IL_0000: ldstr "" IL_0005: ldarg.0 IL_0006: ldfld int32 integer::x IL_000b: box [mscorlib]System.Int32 IL_0010: call string string::Concat(object, object) IL_0015: ret } // end of method integer::ToString } // end of class integer .class public auto ansi beforefieldinit rational extends [mscorlib]System.Object implements class addable`1 { .field assembly int32 n .field assembly int32 d // method line 5 .method public hidebysig specialname rtspecialname instance default void '.ctor' (int32 a, int32 b) cil managed { // Method begins at RVA 0x208a // Code size 21 (0x15) .maxstack 8 IL_0000: ldarg.0 IL_0001: call instance void object::'.ctor'() IL_0006: ldarg.0 IL_0007: ldarg.1 IL_0008: stfld int32 rational::n IL_000d: ldarg.0 IL_000e: ldarg.2 IL_000f: stfld int32 rational::d IL_0014: ret } // end of method rational::.ctor // method line 6 .method public final virtual hidebysig newslot instance default class rational 'add' (class rational R) cil managed { // Method begins at RVA 0x20a0 // Code size 50 (0x32) .maxstack 3 .locals init ( int32 V_0, int32 V_1) IL_0000: ldarg.1 IL_0001: ldfld int32 rational::d IL_0006: ldarg.0 IL_0007: ldfld int32 rational::d IL_000c: mul IL_000d: stloc.0 IL_000e: ldarg.0 IL_000f: ldfld int32 rational::n IL_0014: ldarg.1 IL_0015: ldfld int32 rational::d IL_001a: mul IL_001b: ldarg.1 IL_001c: ldfld int32 rational::n IL_0021: ldarg.0 IL_0022: ldfld int32 rational::d IL_0027: mul IL_0028: add IL_0029: stloc.1 IL_002a: ldloc.1 IL_002b: ldloc.0 IL_002c: newobj instance void class rational::'.ctor'(int32, int32) IL_0031: ret } // end of method rational::add // method line 7 .method public virtual hidebysig instance default string ToString () cil managed { // Method begins at RVA 0x20de // Code size 33 (0x21) .maxstack 8 IL_0000: ldarg.0 IL_0001: ldfld int32 rational::n IL_0006: box [mscorlib]System.Int32 IL_000b: ldstr "/" IL_0010: ldarg.0 IL_0011: ldfld int32 rational::d IL_0016: box [mscorlib]System.Int32 IL_001b: call string string::Concat(object, object, object) IL_0020: ret } // end of method rational::ToString } // end of class rational .class public auto ansi beforefieldinit cell`1<(class addable`1) T> extends [mscorlib]System.Object { .field assembly !0 car .field assembly class cell`1 cdr // method line 8 .method public hidebysig specialname rtspecialname instance default void '.ctor' (!T a, class cell`1 b) cil managed { // Method begins at RVA 0x2100 // Code size 21 (0x15) .maxstack 8 IL_0000: ldarg.0 IL_0001: call instance void object::'.ctor'() IL_0006: ldarg.0 IL_0007: ldarg.1 IL_0008: stfld !0 class cell`1::car IL_000d: ldarg.0 IL_000e: ldarg.2 IL_000f: stfld class cell`1 class cell`1::cdr IL_0014: ret } // end of method cell`1::.ctor // method line 9 .method public hidebysig instance default int32 length () cil managed { // Method begins at RVA 0x2118 // Code size 28 (0x1c) .maxstack 2 .locals init ( int32 V_0, class cell`1 V_1) IL_0000: ldc.i4.0 IL_0001: stloc.0 IL_0002: ldarg.0 IL_0003: stloc.1 IL_0004: br IL_0014 IL_0009: ldloc.0 IL_000a: ldc.i4.1 IL_000b: add IL_000c: stloc.0 IL_000d: ldloc.1 IL_000e: ldfld class cell`1 class cell`1::cdr IL_0013: stloc.1 IL_0014: ldloc.1 IL_0015: brtrue IL_0009 IL_001a: ldloc.0 IL_001b: ret } // end of method cell`1::length // method line 10 .method public hidebysig instance default !T sum () cil managed { // Method begins at RVA 0x2140 // Code size 54 (0x36) .maxstack 2 .locals init ( !T V_0, class cell`1 V_1) IL_0000: ldarg.0 IL_0001: ldfld !0 class cell`1::car IL_0006: stloc.0 IL_0007: ldarg.0 IL_0008: ldfld class cell`1 class cell`1::cdr IL_000d: stloc.1 IL_000e: br IL_002e IL_0013: ldloca.s 0 IL_0015: ldloc.1 IL_0016: ldfld !0 class cell`1::car IL_001b: constrained. !0 IL_0021: callvirt instance !0 class addable`1::'add'(!0) IL_0026: stloc.0 IL_0027: ldloc.1 IL_0028: ldfld class cell`1 class cell`1::cdr IL_002d: stloc.1 IL_002e: ldloc.1 IL_002f: brtrue IL_0013 IL_0034: ldloc.0 IL_0035: ret } // end of method cell`1::sum } // end of class cell`1 .class public auto ansi beforefieldinit polylists extends [mscorlib]System.Object { // method line 11 .method public hidebysig specialname rtspecialname instance default void '.ctor' () cil managed { // Method begins at RVA 0x2182 // Code size 7 (0x7) .maxstack 8 IL_0000: ldarg.0 IL_0001: call instance void object::'.ctor'() IL_0006: ret } // end of method polylists::.ctor // method line 12 .method public static hidebysig default void Main () cil managed { // Method begins at RVA 0x218c .entrypoint // Code size 50 (0x32) .maxstack 2 .locals init ( class cell`1 V_0, class cell`1 V_1) IL_0000: ldc.i4.3 IL_0001: newobj instance void class integer::'.ctor'(int32) IL_0006: ldnull IL_0007: newobj instance void class cell`1::'.ctor'(!0, class cell`1) IL_000c: stloc.0 IL_000d: ldc.i4.1 IL_000e: ldc.i4.4 IL_000f: newobj instance void class rational::'.ctor'(int32, int32) IL_0014: ldnull IL_0015: newobj instance void class cell`1::'.ctor'(!0, class cell`1) IL_001a: stloc.1 IL_001b: ldloc.0 IL_001c: callvirt instance int32 class cell`1::length() IL_0021: call void class [mscorlib]System.Console::WriteLine(int32) IL_0026: ldloc.1 IL_0027: callvirt instance int32 class cell`1::length() IL_002c: call void class [mscorlib]System.Console::WriteLine(int32) IL_0031: ret } // end of method polylists::Main } // end of class polylists */