Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to force use of extension method instead of instance method with params?

I'm having trouble getting the C# compiler to call an extension method I created, since its preferring an instance method with a params argument instead.

For example, say I have the following class and its method:

public class C
{
    public void Trace(string format, params object[] args)
    {
         Console.WriteLine("Called instance method.");
    }
}

And and extension:

public static class CExtensions
{
    public void Trace(this C @this, string category, string message, params Tuple<string, decimal>[] indicators)
    {
        Console.WriteLine("Called extension method.");
    }
}

In my sample program:

public void Main()
{
    var c = new C();

    c.Trace("Message");
    c.Trace("Message: {0}", "foo");
    c.Trace("Category", "Message", new KeyValuePair<string, decimal>("key", 123));
}

All calls print Called instance method..

I do not have access to class C, obviously, or I wouldn't bother creating extension methods, and my extension is important because it would allow my users to continue using a class that they already know with some added value.

From what I've understood, the compiler will favor instance methods over extension methods, but is this the only rule? That would mean that any class with a method that looks like Method(string format, params object[] args) cannot have extension methods with a first parameter of type string.

Any explanation on the reasons for this behavior or a way to work around it (that is not "simply call CExtensions.Trace(c, "Category", ...") would be greatly appreciated.

like image 237
madd0 Avatar asked Nov 08 '11 10:11

madd0


People also ask

Is it possible to override the extension method?

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.

Can you add extension methods to an existing static class?

The main advantage of the extension method is to add new methods in the existing class without using inheritance. You can add new methods in the existing class without modifying the source code of the existing class. It can also work with sealed class.

Can extension methods access private methods?

According to Microsoft, In fact, extension methods cannot access private variables in the type they are extending.

When would you not use an extension method?

When you're not sure which Type is the one to extend, don't use extension methods. For example, to build a house from brick and mortar I can extend brick with brick.


2 Answers

You can't use extensions to "take over" existing class methods.

If the call works without the extension, the behaviour should not change when you add the extension. The reason for this is that existing code should not break by introducing an extension later on.

You have to use a different name for it, or use parameter types different from the class method.

like image 85
Guffa Avatar answered Oct 11 '22 22:10

Guffa


You cannot directly. A method on the target instance is always preferred over an extension method. The only way to do this (while keeping the names the same etc) is to use the CExtensions.Trace approach (in the question).

In some cases, a trick here would be to use some base-class of C or interface that C implements, but which does not have a Trace method, and re-type the variable, and add an overload on CExtensions, i.e.

IFoo foo = c;
foo.Trace(...);
like image 4
Marc Gravell Avatar answered Oct 11 '22 21:10

Marc Gravell