Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can I not convert a Foo<Bar> to IFoo<IBar>

Tags:

c#

.net

Why can I not convert a Foo<Bar> to IFoo<IBar>.

If I try I get:

There is no implicit reference conversion from Foo<Bar> to IFoo<IBar>

like image 359
magol Avatar asked Dec 07 '22 19:12

magol


2 Answers

It would work if you were using C# 4 and IFoo were declared as:

public interface IFoo<out T>

assuming that Bar implements IBar and Foo<T> implements IFoo<T>.

However, it could only be declared that way if it were safe. It's not safe if T values "go into" the API as well as coming out. For example:

public interface IFoo<T>
{
    T Value { get; set; }
}

This can't be covariant in T, as otherwise you could write:

public class StringFoo : IFoo<string>
{
    public T Value { get; set; }
}

IFoo<string> fooString = new StringFoo(); // That's fine
IFoo<object> fooObject = fooString;       // This isn't, because...
fooObject.Value = new Object();           // ... this would violate type safety

Read Eric Lippert's long blog series on generic variance for much more information.

like image 109
Jon Skeet Avatar answered Dec 31 '22 01:12

Jon Skeet


In order for this to work, three things need to be true:

  1. Bar must implement IBar
  2. Foo must implement IFoo
  3. IFoo<T> must be covariant in T (like this: IFoo<out T>)
like image 41
Andrew Hare Avatar answered Dec 31 '22 00:12

Andrew Hare