I am having trouble understanding why an extension method for a generic interface is failing to be found if implemented a second time.
Here's a contrived example to illustrate the issue. Initially, this works. I will break it in a moment:
public interface IContains<in TBeer, out TPack>
{
TPack Add(TBeer element);
}
public class Coors { }
public class Miller { }
public class SamplerPack : IContains<Coors, SamplerPack>
{
public SamplerPack Add(Coors element)
{
// logic removed for brevity
return this;
}
}
public static class Extension
{
public static TPack CoorsExtension<TPack>(this IContains<Coors, TPack> element)
{
// logic removed for brevity
return (TPack) element;
}
}
With this setup the extension method CoorsExtension works:

If I implement the generic interface again like this:
public class SamplerPack : IContains<Coors, SamplerPack>, IContains<Miller, SamplerPack>
{
public SamplerPack Add(Coors element)
{
// Add logic removed for brevity
return this;
}
public SamplerPack Add(Miller element)
{
// Add logic removed for brevity
return this;
}
}
Extension method is no longer found:
'SamplerPack' does not contain a definition for 'CoorsExtension' and no extension method 'CoorsExtension' accepting a first argument of type 'SamplerPack' could be found (are you missing a using directive or an assembly reference?)
I would like to understand why this is failing, and if possible, how to fix it.
Well, your second implementation has a major difference : it tries to implement two times the generic interface, with different types...
So you can't anymore access the interface extension method from an instance of the class, but only from an "explicit instance" of one of the two interfaces.
Which means you can't use var anymore, but something like
IContains<Coors, SamplerPack> beer = new SamplerPack();
beer.CoorsExtensions();
or cast beer to the desired interface before calling the desired extension method.
var beer = new SamplerPack();
((IContains<Coors, SamplerPack>)beer).CoorsExtensions();
By the way, I would rather go for two classes (one for Coors, one for Miller) to avoid these kind of confusions (these two class may inherit from an abstract base class to avoid redundant implementations of Add).
And of course, a theorical explanation on why the compiler doesn't complain would be usefull...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With