/* Polymorphic linked lists - first version */ using System; using numbers; public class cell { private object head; // general head private cell tail; public object CAR { get { return head; } } public cell CDR { get { return tail; } } public cell(object h, cell t) {head=h; tail=t;} public int length() // internal visitor { int ax = 0; // accumulator for (cell i=this;i!=null;i=i.tail) ax++; return ax; } public void print() { Console.Write(head + " "); if (tail==null) Console.Write("\n"); else tail.print(); } // but the above form of polymorphism is trivial. // now I want to be able to add one to the head, but I don't know // if the head is a numerical type, or an int or rational! // Another way to do it would be to use a superclass for all numerical // types, but that would disallow other lists. public void add1() { if (head is int) head = (int)head + 1; else if (head is rational) ((rational)head).add(1); if (tail !=null) tail.add1(); // Might as well do it in C - there's no auto-dispatch here. // you might think the if-else can be avoided if we could just // overload the ++ operator, but that won't work either, because // the static type of 'head' is object, which doesn't have a ++ // operator. You must type cast it to a type that allows for ++. // that is, you'll be able to do ((number)head)++; assuming the // type number (be it a superclass or interface), allows for ++. } } // cell class public class polylist1 { public static int length(cell l) // external visitor { if (l==null) return 0; else return 1+length(l.CDR); } public static void Main() { cell l; l = new cell(3,new cell(new rational(1,2),new cell(5,null))); Console.WriteLine(length(l)); l.print(); l.add1(); l.print(); } } //complie with csc /r:number.dll polylist.cs