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)
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.