In mijn vorige blog ben ik ingegaan op Optional en Named parameters. Naast deze makkelijk inzetbare functionaliteit is er natuurlijk nog meer te melden. Deze post gaat over Dynamic lookup en het Dynamic Type.

In mijn vorige blog ben ik ingegaan op Optional en Named parameters. Naast deze makkelijk inzetbare functionaliteit is er natuurlijk nog meer te melden. Deze post gaat over Dynamic lookup en het Dynamic Type.
Dynamic Lookup
Normaal gesproken zijn objecten binnen C# van een bepaald type. De compiler zal controleren of de handelingen die je op het object wil loslaten ook daadwerkelijk kunnen en zo niet, dan zal je code niet compileren. Met Dynamic lookup is het mogelijk om deze controle niet compile-time te laten plaats vinden, maar run-time. Een object (of het nu afkomstig is van COM, IronPython, reflection of iets dergelijks) kun je daardoor in je code gebruiken en de runtime gaat tijdens het uitvoeren pas bepalen wat er eigenlijk moet gebeuren.
Dynamic Language Runtime
De nieuwe versie van C# zal hiervoor een nieuwe API bevatten: de Dynamic Language Runtime (DLR). Deze DLR zorgt er dus voor dat Dynamic lookup mogelijk wordt en bevat bijvoorbeeld caching mechanismen zodat het ook efficiënt gebeurd.
Het Type dynamic
Er is een nieuw type beschikbaar ‘dynamic’. Objecten van dit type zijn dus dynamisch te gebruiken.
dynamic dyn_obj = GetDynamicObject(…);
dyn_obj.DoSome("test");
De compiler heeft dus geen idee wat de methode ‘DoSome’ is, of deze bestaat en wat deze doet. Van de compiler mag je dus alles doen met een dynamic object, zonder waarschuwingen of foutmeldingen. De runtime zal op zoek gaan naar de juiste manier om ‘DoSome’ aan te roepen. Als de methode ‘DoSome’ tijdens het uitvoeren niet blijkt te bestaan zal er een runtime exception optreden.
Net als bij het type ‘Object’ kunnen andere types van en naar een dynamic ‘ge-boxed’ en ‘ge-unboxed’ worden.
dynamic dyn_obj = 1;
int number = dyn_obj;
Naast het aanroepen van methoden is het ook mogelijk om fields, properties, indexers en operators van het object te gebruiken en is deze als delegate aan te roepen.
dynamic dyn_obj = GetDynamicObject(…);
dyn_obj.DoSome("test");
int x = dyn_obj.Prop;
dyn_obj.someField = x;
dyn_obj["a"] = dyn_obj["b"];
x = dyn_obj + 1;
bool val = dyn_obj("test" , 5);
Afhankelijk van de herkomst van het dynamic object zal de runtime een bepaalde actie ondernemen.
Bij COM objecten zullen de methodes dynamisch worden aangeroepen via IDispatch. Hierdoor kunnen COM objecten worden gebruikt zonder Primary Interop Assembly. Bij een ‘normaal’ .Net object wordt gebruik gemaakt van reflectie om de juiste aanroep op het object te doen. Daarnaast is het nog mogelijk dat het object een implementatie bevat van de IDynamicObject interface. Dergelijke objecten zullen worden gevraagd om zelf te zorg te dragen dat de handelingen uitgevoerd worden.
Overloads
Objecten van het dynamic type kunnen ook als parameter worden meegegeven aan een methode van een ander object. Laten we eens kijken naar het volgende voorbeeld:
Class Test{
       public int Add(int a, int b){
       return a + b;
       }
       public string Add(string a, string b){
       return a + b;
       }
       }
Stel je wilt een aanroep doen van de ‘Add’ methode, maar de objecten die je binnen krijgt zijn van het type dynamic. Je hoeft geen extra overload te maken die een dynamic argument verwacht. Maar als er verschillende overloads zijn, welke wordt dan uiteindelijk gebruikt? Ook dit wordt run-time opgelost. Blijken de dynamic objecten Integers te zijn, dan zal de eerste overload gebruikt worden. Zijn het strings, dan zal dus de tweede overload gebruikt worden.
Test t = new Test();
dynamic d1 = 10;
dynamic d2 = 50;
dynamic val = t.Add(d1 , d2);
In dit geval wordt dus de eerste overload gebruikt.
Meer Informatie
In deze blog zal ik regelmatig nieuwe berichten over C# versie 4 posten. Voor de Virtual PC met Visual Studio 2010 kun je hier terecht: http://www.microsoft.com/downloads