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.
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.
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.
According to Microsoft, In fact, extension methods cannot access private variables in the type they are extending.
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.
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.
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(...);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With