泛型类协方差

时间:2013-09-29 10:45:19

标签: c# covariance

是否可以在C#中编译以下代码?我在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
}

3 个答案:

答案 0 :(得分:6)

不,这在C#中是不合法的。 C#4及更高版本支持通用接口和通用委托在使用引用类型构造时的协方差和逆变。例如,IEnumerable<T>是协变的,所以你可以说:

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

但不是

List<Animal> animals = giraffes;

因为动物名单中可以插入一只老虎,但长颈鹿名单却不能。

在C#中进行协方差和逆变的网络搜索,你会发现很多文章。

答案 1 :(得分:3)

看起来.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.
}

答案 2 :(得分:0)

你不能使用像这样的泛型.list类型是IInterface但你尝试将Class1类型添加到list.it应该如下..

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