Showing posts with label Reflection. Show all posts
Showing posts with label Reflection. Show all posts

Tuesday, January 18, 2011

Dynamic method binding

One of the added features to C# 4.0 was dynamic objects. It gives late binding to C# so everything doesn't have to checked at compile time. In some cases this makes it a lot easier to use reflection as you don't have to use any of the .net API's to do so. You can act directly on the object as if you had the type at hand. All you need to know is the footprint of what you need to access. Most examples emphasize how this can be used when integrating with other technologies like old com objects etc, but I have been looking for usages outside that scope. One is ofcourse reflection, another one is dynamic method binding that I will try and explain.

Basic OO with cats and dogs.



I create the traditionel object structure to support me explain what I mean. Animal is a pure abstract concept, Cat is an Animal and so is Dog.

Make the animals make som noise
I have created a MakeSound method that operates on the interface and one for each of the classes. As there is no general sound that will match any animal I just print ????? to the screen when in the context of Animal.
What I want is to have a list of animals containing cats and dogs and then call the MakeSound for each animal in the list.
As in C# < 4.0
The big question is what method is actually called. The answer is that the method binding is done at compile time, the best match is the method that takes the interface as a parameter. All the objects are treated as of type Animal. This is the way it has always worked in C# and it should therefore be no surprise if you have been in a similar situation. The output is as follows.

Result of program with static method binding

Use of var keyword

With C# 3.5 the var keyword was introduced. One might think that this changed the way this would work as the programmer no longer defines the type and the framework should therefore be able to select a better method implementation automatically. The answer is that the var is just a way to have the compiler derive the type instead of the programmer. This is all done at compile time and the best match will therefore still be the method that operates on the interface.

Handle the objects as dynamic instead
The dynamic keyword was introduced with C# 4.0 and this changes the possibilities when writing code like this. When treating every object in the list as a dynamic object, the compiler won't bind to any method but will leave it to the runtime to make the connection. This means that the type of every object is considered and handled on its own and the items in the list won't nescesarily result in the same method being called. This can be very usefull when iterating tree structures etc. The downside is that you will have no intellisense and no compile time validation when writing the code.

As the best methods are now called, the output will be cat and dog specific.

Output when treating the objects as dynamic
This can definately clean up some of my code. I might write a comment along with the code so that people in the future can figure out my intentions.

Related posts:
Wrapping objects with interfaces
Dynamic duck typing in .Net 3.5

Tuesday, November 10, 2009

Dynamic duck typing in .Net 3.5

I just saw a post about wrapping reflection as extension methods.

Reflection as such is not rocket science. Reflection is for discovering features of objects you don't know how is structured at compile time or it is for interaction with objects you know how operate but don't have a type for.
It's not a big problem to use reflection to access regular properties or methods. The extension methodsI created for wrapping properties and non generic methods are merely wrapping some simple reflection calls.

Alright, let's get to it:

Setting the value of a property.
o.SetValue<string>("Title","Some title");

Getting the value of a property.
string title = o.GetValue<string>("Title");

Calling a method
o.CallMethod("Dostuff");

With generic methods its a different story. I can't find it just by a name. I have to find the version that supports generics. Not only do I need to provide parameters for the method call but also the generic types. This means I can't wrap a generic method call in just one extension method.

This is the situation I want to handle. I have an object and want to find a Dao object for it to be able to save it. If you know the type compile it could be something like this:

IDao dao = factory.GetDao<Blog>();
dao.Save(blog);

The same code executed with my new extension methods:

object o;// object you want to save
object dao = factory.GetMethod<object>("GetDao",o.GetType()).Call();
dao.CallMethod("Save",o);

It's a bit more verbose than direct code, but a lot more compact and precise than if you had to use the System.Reflection namespace. The GetMethod method gathers the name of the method together with a list of types that defines the methods generic properties. The Call method accepts the parameters for the method call and invokes the method.

The source for the extension methods can be found here.

Thursday, April 03, 2008

Reflection on Lazy loading

No, I'm not going to reflect on lazy loading. :)

By lazy loading I mean having an object model without all of the objects being loaded (from database) at once. If I for instance have a User object with an Organisation, I don't necessarily want the Organisation object to be loaded when the User is loaded. Not loading everything at once speeds things up because you can control what is retrieved from the database and what is not. Anyway, enough about why lazy load. NHibernate implements lazy loading by creating a proxy class that inherits the class of the object. The moment you try to access your object, the object is retrieved from the database. The object you asked for has been loaded internally in the NHibernate object and it will be transparent to you because all your interaction with the object will be passed on to it

The object model you want

The problem starts when you start to use reflection on your objects. The Organisation object on the User is actually not a Organisation, but a subclass generated by NHibernate. If the object you are trying to access is an ExtendedOrganisation, you can't cast it to the type you want because its type is defined by the reference on your User object.


Because NHibernate caches its loaded object it can be hard to tell in advance whether an object will be a proxy or not. If you ask NHibernate to load a Organisation object, you will get a proxy class object if NHibernate has cached it as a lazy loaded object beforehand.

The objects NHibernate gives you

If you want reflection on your objects that may be lazy loaded, you can make generic method where you also have to give the type. When applying reflection you will have to use the generic type for your analysis. If you object has been loaded with a wrong type, you can make a property that returns the same instance. Because the NHibernate proxy contains a reference to the real object and passes all method calls etc. through you can make it work just by returning "this".

Some of the components in .Net that consume list of objects do this by reflecting on the first object in the list, using this type to handle all the objects in the list. You can overcome this by implementing a TypeDescriptionProvider and registering it like described by Ayende. The problem with this is that it will change the way your types are handled throughout your application. You would no longer be able to have a list of ExtendedOrganisations.
The much nicer approach would of course be to have type aware components through Generics.