How do I resolve extension method ambiguity errors in my extensions library?

Viewed 1001

Lets say i have an extension method.

public static string DoSomething(this IInterfaceA @this) ...

and

public static string DoSomething(this IInterfaceB @this) ...

but if I have a class that implements both interfaces, is it possible, for an extension library, to indicate which one it should prefer?

2 Answers

Short answer - No, it is not possible.

Long answer: An extension method is but a static method that accepts parameters and contains the keyword this. Intellisense scans the code to find all extension methods and provides us with a syntactic sugar that allows to call them on an instance of the class same as normal methods.

Interface on the other hand describes object behavior and is used for grouping and separating/segregating objects by what they do:

IBird { void Fly(); }
IBug { void Crawl(); }

class Parrot : IBird {}
class Ant : IBug {}

If we have something like:

IGlidingBird { void Fly(); }  // and
IFlappingBird { void Fly(); }

Then it is likely that we have bad design because the interface being a container of virtual methods shouldn't know anything about the actual implementation of it.

In the example code you'll see a compile time error: 'The call is ambiguous between the following methods...'.

While you could cast the object to one of the interface types to let the compiler know which methods to use:

((IInterfaceA)instance).DoSomething()
((IInterfaceB)instance).DoSomething()

It might be a good moment to pause and think whether it is possible to change the design and avoid this problem altogether.

Yes, it's possible.

You need to declare another extension method with a generic that has both types as constraints.


public static string DoSomething<T>(this T @this) where T : IInterfaceA, IInterfaceB
{  
    ...
}

Now there will be no ambiguity, since the compiler prefers the most constrained extension method over other extension methods.

Related