General covariance

Is it possible to make the following code in C #? I am compiling similar to Java.

public interface IInterface
{
    ...
}

public class Class1 : IInterface
{
    ...
}

public abstract class Base<T> where T : IInterface
{
    ...
}

public class Class2<T> : Base<T> where T : IInterface
{
    ...
}

.
.
.

public SomeMethod()
{
    List<Base<IInterface>> list = new List<Base<IInterface>>();
    Class2<Class1> item = new Class2<Class1>();
    list.Add(item); // Compile error here
}
+4
source share
3 answers

No, this is not legal in C #. C # 4 and above support covariance and contravariance of common interfaces and common delegates when they are built using reference types. So, for example, IEnumerable<T>is covariant, so you can say:

List<Giraffe> giraffes = new List<Giraffe>() { ... };
IEnumerable<Animal> animals = giraffes;

but not

List<Animal> animals = giraffes;

Because the tiger can be included in the list of animals, but the list of giraffes cannot be.

Do a web search on covariance and contravariance in C # and you will find many articles on it.

+5
source

, .NET Framework 4.0 . , , .

public interface IInterface
{
    ...
}

public class Class1 : IInterface
{
    ...
}

public interface IBase<out T> where T: IInterface
{
    // Need to add out keyword for covariance.
}

public class Base<T> : IBase<T> where T : IInterface
{
    ...
}

public class Class2<T> : Base<T> where T : IInterface
{
    ...
}

.
.
.

public SomeMethod()
{
    List<IBase<IInterface>> list = new List<IBase<IInterface>>();
    Class2<Class1> item = new Class2<Class1>();
    list.Add(item); // No compile time error here.
}
+3

, this.list, IInterface, Class1 . .

        List<Base<Class1>> list = new List<Base<Class1>>();
        Class2<Class1> item = new Class2<Class1>();
        list.Add(item); 
0

All Articles