4 September 2013

A look at extension methods and method overloading

Extension methods are a great way to inject our own methods into some other classes which greatly improve the extension of functionality, code re-use etc. Everything is well and good. However, we often miss some important details which might frustrate us. One such thing with extension methods is - CLR always chooses the closest method than closest match when an overloaded extension method is defined. Confused? Hmm... Let me take you directly into some code.

Below is simple class hierarchy.

class Parent {}

class Child : Parent {}

class GrandChild: Child {}

Very straight forward, isn't it? Now let me create a business class as below,

class MyClass
{
   public void Display(Parent objA) //------------------------------- (A)
   {
       Console.WriteLine("I am not an extension method");
   }
}

And now let me define an overladed extension method for MyClass,

static class Extensions
{
   public static void Display(this MyClass m, Child c) //-------------(B)
   {
       Console.WriteLine("I am an extension method");
   }
}

Ok. Done with setup. Before going further, you might want to have a relook at above classes and their relations. Anyways, below is my consumer class wherein I want to create an object of MyClass and call Display on it.

class Consumer
{
    public static void Main()
    {
       Child child = new Child();

       MyClass obj = new MyClass();
       obj.Display(child);
    }  
}

So, Could you guess what would be the output of above code? From our OOP and C# knowledge we tell that it will call extension method Display because it exactly matches the caller signature. Right? However, that's not correct. In this case, CLR prefers non-extension method (A) over extension method (B) even though the (B) perfectly matches caller's signature. It means, CLR picks the method 'Display' which is inside MyClass than the extension method 'Display' which is outside of MyClass.

Now just comment out Display method inside and run the code and  this time the extension method is called. This perfectly makes sense because when a method is called, CLR first search MethodInfo table of the class on which the method is being called. If it find a multiple method definitions in the same class, it chooses the best match. If it doesn't any entry, it will search up the inheritance hierachy. If it doesn't find any match, then it will look for any extension methods.

I hope you enjoyed reading this post and also might save you some time  when you encounter similar issues related to extension methods.

2 comments: