Zoidbergseasharp
Zoidbergseasharp

Reputation: 4519

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

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?

Upvotes: 6

Views: 2498

Answers (3)

Richard Flora
Richard Flora

Reputation: 1

You can pass your instance variable into your static extension method replacing the this parameter with your variable.

ex:

namespace System { public static class ExceptionExtensions { public static string GetFullExceptionMessage(this Exception ex) { ...

implemented as

{ catch(Exception ex) { System.ExceptionExtensions.GetFullExceptionMessage(ex);

Upvotes: 0

Zoidbergseasharp
Zoidbergseasharp

Reputation: 4519

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.

Upvotes: 5

Fabjan
Fabjan

Reputation: 13676

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.

Upvotes: 5

Related Questions