I'm confused by a problem we have in our project. I tried to simplify it to reproduce the effect:

interface IBar { }

class Bar : IBar {}

interface IFoo<T> where T : IBar { }

class Foo<T> : IFoo<T> where T : IBar { }


class Class1
{
    public void DoTheFoo<T>(T bar) where T : IBar
    {}

    public void DoTheFoo<T>(IFoo<T> foo) where T : IBar
    {}


    public void Test()
    {
        var bar = new Bar();
        var foo = new Foo<Bar>();

        DoTheFoo(bar); // works

        DoTheFoo<Bar>(foo); // works
        DoTheFoo((IFoo<Bar>)foo); // works
        DoTheFoo(foo); // complains
    }
}

To me this looks fine, but the compiler complains on the last call, because it tries to DoTheFoo<T>(T bar), instead of DoTheFoo<T>(IFoo<T> foo) and complains that the argument type does not fit.

  • When I remove the method DoTheFoo<T>(T bar), the last call works!
  • When I change it to DoTheFoo<T>(Foo<T> foo), it works, but I can't use that

It is not too hard to work around this in our current code. But it is a) strange and b) too bad that we can't have these two overloaded methods.

Is there a common rule that explains this behaviour? Is it possible to make it work (except of giving the methods different names)?

Edit
Report