The code is a little weird, so bear with me (keep in mind this scenario did come up in production code).
Say I've got this interface structure:
public interface IBase { }
public interface IChild : IBase { }
public interface IFoo<out T> where T : IBase { }
With this extension method class built around the interfaces:
public static class FooExt
{
public static void DoSomething<TFoo>(this TFoo foo)
where TFoo : IFoo<IChild>
{
IFoo<IChild> bar = foo;
//foo.DoSomethingElse(); // Doesn't compile -- why not?
bar.DoSomethingElse(); // OK
DoSomethingElse(foo); // Also OK!
}
public static void DoSomethingElse(this IFoo<IBase> foo)
{
}
}
Why doesn't the commented-out line in DoSomething compile? The compiler is perfectly happy to let me assign foo to bar, which is of the same type as the generic constraint, and call the extension method on that instead. It's also no problem to call the extension method without the extension method syntax.
Can anyone confirm if this is a bug or expected behaviour?
Thanks!
Just for reference, here's the compile error (types abridged for legibility):
'TFoo' does not contain a definition for 'DoSomethingElse' and the best extension method overload 'DoSomethingElse(IFoo)' has some invalid arguments
outwouldn't work)outcovariant generic definition of theIFoointerface?DoSomethingElse(foo)andDoSomethingElse(bar)? The way you have it, foo and bar don't have any member functionsout Tinstead ofin T. The IChild cannot be cast intoIFoo<IBase>.