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.