Type Systems Demystified |
Written by Nikos Vaggalis | |||||||
Friday, 19 February 2010 | |||||||
Page 4 of 6
C# and ReflectionIn essence reflection is used when you have an assembly with no compile time information on it and you must load it at runtime. By using Reflection you can then interrogate it from your code dynamically and get all the type info from within. This also forms the basis of plug-and-play Component architecture where you do interface based programming by separating interface from implementation. Back to our example we said that in VB.net using "strict off" enables late-binding. In C# there is no such directive so we have to use the Reflextion API for the same purpose. Example 5class Class1 class Program Type T = myobj.GetType(); object[] param = new object[2]; int myresult = Console.WriteLine( } I'm not going to get into details but this example is the equivalent of the example in VB.net with strict off. It requires more lines of code and at the same time proves a bit cumbersome. But this is going to be changed by the introduction of a new type called dynamic, which adds dynamic language capabilities to C#. Dynamic typeThe code inside the Main method of the above example in Reflection could be replaced by using the new Dynamic type and become as small as: dynamic myobj = new Class1(); Example 5ausing System; namespace ConsoleApplication4 class Program Console.WriteLine( Again, it does not do compile time checking. If something goes wrong it will be dicovered at runtime dynamic d = MakeDynamicType(); Single versus multiple method dispatchOne marvellous use of the dynamic type is that it allows for runtime method overloading or multiple method dispatch, an advanced polymorphic concept. In common with most OOP languages C# and VB.net are single dispatch languages and resolve method overloading at compile time. This means that the method chosen is based on the compile time type and the type of the method parameters. Example 6 class Fruit } class Apple : Fruit } class Class1 public virtual int Method1(Apple a) public virtual int Method1(int x) class Class2 : Class1 public override int Method1(Apple a) return 5; public override int Method1(int x) }
class Program int x = objA.Method1(objF); } The method resolution works like this - objA's compile type is Class1 but runtime type is Class2. To resolve the binding the compile time type is used, that is Class1. Thus a method with name Method1 and argument of type Fruit is looked for. This is public virtual int Method1(Fruit a). Since it is virtual the runtime type is consulted which resolves to Class2' public override int Method1(Fruit a). Although the method is 'virtual' and the runtime type is consulted for looking up the method, it comes a bit too late since the signature of the method is determined at compile time. The same result would also be achieved with late binding/option strict off. In this case although the compile time type information would be totally disregarded and the method look up would be done at runtime, it would also use the compile time parameter type for identifying the method. So at runtime the object's type is Class2 but the argument passed to the method is of compile type Fruit, thus Class2's public override int Method1(Fruit a) is chosen, again. What multiple method dispatch would do differently is that it would choose the method based on the runtime type of the parameter.That is, it would have chosen Class2 public override int Method1(Apple a) Example 7class Fruit } class Apple : Fruit } class Class1 public virtual int Method1( public virtual int Method1(int x) class Class2 : Class1 public override int Method1( public override int Method1(int x) } class Program Class1 objA = new Class2(); int x = objA.Method1(objF); //object objB = new Apple(); } Just to see the difference between Object and Dynamic uncomment the following lines //object objB = new Apple(); and run the example again. You get the following compile time errors: Error 1 The best overloaded method Error 2 Argument 1: cannot convert from This proves that Object is treated differently by Dynamic - the Object type is used for compile time method resolution, whereas Dynamic is used for runtime method resolution This advanced polymorphic concept was formerly supported only by Reflection but now will be supported by the Dynamic type in the .NET environment, and in the forthcoming Perl6 by using 'multi' subroutines. Of course since Perl has no compile time type safety it could not have method overloading at compile time. Were method overloading in Perl to exist it would be a runtime affair by definition. Of course for it to work the methods or subs would require typed parameters which do not exist in earlier Perl versions and thus to employ MMD you had to resort to big IF..Then clauses. But now the Perl6 type system will allow for this sort of functionality. <ASIN:1590594525> <ASIN:1565922204> <ASIN:1430225297> |
|||||||
Last Updated ( Friday, 09 November 2012 ) |