Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extension method vs static method precedence

Consider the following program:

class A
{
    public static void Foo()
    {
    }
}

static class Ext
{
    public static void Foo(this A a)
    {
    }
}

class Program
{
    static void Main(string[] args)
    {
        var a = new A();
        a.Foo();
    }
}

This fails to compile, with the error:

Member 'Test.A.Foo()' cannot be accessed with an instance reference; qualify it with a type name instead

Why is the compiler ignoring the extension method?

like image 291
Eren Ersönmez Avatar asked Mar 28 '12 18:03

Eren Ersönmez


People also ask

Are static methods more performant?

They are faster — Static methods are slightly faster than instance methods because in instance methods, you are also working with an implicit this parameter. Eliminating that parameter gives a slight performance boost in most programming languages.

What is an advantage of using extension methods?

The only advantage of extension methods is code readability.

Are extension methods always static?

An extension method must be a static method. An extension method must be inside a static class -- the class can have any name. The parameter in an extension method should always have the "this" keyword preceding the type on which the method needs to be called.

Why do extension methods need to be in a static class?

It is compulsion that the Extension method must be in a Static class only so that only one Instance is created. For example, if you place the following in ASP.Net page it will not work. Though error will not come, but you will not see the method available.


1 Answers

What you are trying to do isn't allowed. The C# MSDN Extension Method Article specifically states that:

You can use extension methods to extend a class or interface, but not to override them. An extension method with the same name and signature as an interface or class method will never be called. At compile time, extension methods always have lower priority than instance methods defined in the type itself.

Thank goodness it isn't allowed as that would just be awful to have to maintain.


EDIT: So people are saying that static methods aren't instance methods, which is correct. But try doing this:

class A
{
   public static void Foo() {}
   public void Foo() {}
}

That won't compile either because of a name ambiguity. That is exactly what would happen if you were allowed to use the extension method. It would introduce the exact same ambiguity. Now, given that one method is static and one is instance, should that mean that there is no ambiguity, perhaps. But at the current state it does introduce ambiguity which is yet another reason why it wouldn't be allowed.

Edit #2: From a comment @ErenErsonmez made:

However, as long as the extension method doesn't have the same signature as an instance method, I don't understand how it could ever cause ambiguity with a static method

If you change the signature of the extension method it will definitely work. So the following will work:

class A
        {
            public static void Foo() { }
        }

    static class Ext
    {
        public static void Foo(this A me, int i)
        { }
    }
    class Program
    {
        static void Main(string[] args)
        {
            A a = new A();
            a.Foo(10);

            Console.ReadLine();
        }
    }

So it looks more like the issue is an ambiguity one and not that there can't ever be an extension method of the same name as a method that already exists.

like image 135
Jetti Avatar answered Oct 07 '22 14:10

Jetti