Extension methods are just glorified static methods that look like instance methods at call time (if the caller so chooses).
The situation you're describing cannot happen because the compiler will flag the call as ambiguous:
interface I1 { }
interface I2 { }
class C : I1, I2 { }
static class Ex1 {
public static void M(this I1 self) { }
}
static class Ex2 {
public static void M(this I2 self) { }
}
...
new C().M(); // ERROR: The call is ambiguous
Extension methods are only in effect if you import the namespace containing the static class with the extension method in the current context (via a using
directive); or if your declarations live in the same namespace as them. So, even though you can create ambiguous declarations, if you add them to different namespaces, then the caller can disambiguate by only importing the desired namespace.
Also, to disambiguate, the caller can call the method as a normal static method:
Ex1.M(new C()); // not ambiguous anymore
Or you can cast to the appropriate interface:
((I1)new C()).M(); // not ambiguous anymore
So, it's not as if you're "inheriting" conflicting members that must be resolved at declaration time, you have both at your disposal, and you have to tell the compiler which one you want to use at call time.
Side note: I find this ability to extend interfaces an interesting way to create a form of mixin in C#. I've written about it before, e.g., here.