Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extension method resolution

I wrote an extension method for String to get a char argument, string.Remove(char). But when I used this, it instead called the default string.Remove(int) method.

Shouldn't the presence of an actual method have higher priority than an implicit conversion?

like image 712
Joan Venge Avatar asked Jul 15 '09 17:07

Joan Venge


2 Answers

Instance methods have priority over extension methods. Your observation is proof of the same.

When resolving which method to call, it will always pick a matching instance method over an extension method... which is intuitive in a way.

Paraphrased from C# in depth,

When the compiler sees that you're trying to call a method which looks like an instance method but is unable to find one, it then looks for extension methods (that are visible based on your using directives). In case of multiple candidates as the target extension method, the one with "better conversion" similar to overloading (e.g. if IChild and IBase both have a similar extension method defined.. IChild.ExtensionMethod is chosen)

Also a hidden code-breaker could be lets say TypeA didn't have SecretMethod as an instance method in Libv1.0. So you write an extension method SecretMethod. If the author introduces an instance method of the same name and signature in v2.0 (sans the this param), and you recompile your source with the latest-n-greatest Libv2.0, all existing calls to the extension method would silently now be routed to the new instance method.

like image 151
Gishu Avatar answered Oct 11 '22 11:10

Gishu


This behavior is correct. The reason is that introducing an extension method should not change the way existing code executes. Code should behave exactly the same with or without this "superfluous" extension method. It may seem counter-intuitive in certain cases (like yours), but happens for a reason.

like image 2
snarf Avatar answered Oct 11 '22 12:10

snarf