1

I have the following interfaces and an implementation of them:

public interface IFoo<in T>
{
    void Notify(T obj);
}

public interface IBar
{
    void DoSomething(IFoo<IBar> fooBar);
}

public class Bar
    : IBar
{
    public void DoSomething(IFoo<IBar> fooBar)
    {
        fooBar.Notify(this);
    }
}

public class Foo
    : IFoo<Bar>
{
    public void Notify(Bar obj)
    {
        Console.WriteLine("Hello world!");
    }
}

When I use this classes in my main program:

internal class Program
{
    private static void Main(string[] args)
    {
        var foo = new Foo();

        var bar = new Bar();
        bar.DoSomething(foo);
    }
}

I get a compile error:

cannot convert from 'Foo' to 'IFoo< IBar >'

However, as Foo implements IFoo< Bar > and Bar implements IBar I don't understand why this cannot be resolved.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
LMF
  • 463
  • 2
  • 10
  • I think you wanted in your interface (covariance) – BradleyDotNET Feb 27 '17 at 18:49
  • If I would do this my Notify(T obj) method would not be compiled. If I remove the 'in' the error remains the same. – LMF Feb 27 '17 at 18:55
  • 1
    Just because `Foo` inherits from `IFoo` and that `Bar` inherits from `IBar` it does **not** mean that `IFoo` inherits from `IFoo`. They are simply not related. This is precisely a duplicate question. – Enigmativity Feb 28 '17 at 03:42
  • OP, in your example, Foo requires a concrete instance of Bar, not an IBar. Try adding another method to Bar that is not in the IBar interface, and you'll see that Foo can access it. If it can access it, then it might use it; if it is using it, it won't be able to work with an IBar. – John Wu Feb 28 '17 at 03:53
  • I reopened this question because it involves contravariance whereas the proposed duplicate does not, and that is a significant difference. The OP's code would actually compile if `IBar.DoSomething` took an `IFoo` argument and the `bar` variable in `Main` were declared to be of type `IBar`, because you can cast an expression of type `IFoo` to `IFoo`. It is thus incorrect to say that `IFoo` and `IFoo` are "simply not related". – Michael Liu Feb 28 '17 at 05:08
  • 1
    Do you understand what the difference between covariance and contravariance is? Your question indicates that you want the interface to be covariant, but you've marked it as contravariant. Read this: http://stackoverflow.com/questions/2184551/difference-between-covariance-contra-variance/2202349#2202349 – Eric Lippert Feb 28 '17 at 05:21
  • Isn't your question answered by the examples shown in the answers here? http://stackoverflow.com/questions/2662369/covariance-and-contravariance-real-world-example – George Stocker Feb 28 '17 at 18:01

0 Answers0