泛型类协方差
本文关键字:方差 泛型类 | 更新日期: 2023-09-27 18:33:17
是否可以用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
}
不,这在 C# 中是不合法的。 C# 4 及更高版本在使用引用类型构造泛型接口和泛型委托时,支持泛型接口和泛型委托的协方差和逆变。 例如,IEnumerable<T>
是协变的,所以你可以说:
List<Giraffe> giraffes = new List<Giraffe>() { ... };
IEnumerable<Animal> animals = giraffes;
但不是
List<Animal> animals = giraffes;
因为动物名单可以插入老虎,但长颈鹿名单不能。
在 C# 中对协方差和逆变进行 Web 搜索,你会发现很多关于它的文章。
看起来 .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.
}
你不能像这样使用泛型.list类型是IInterface,但你尝试将Class1类型添加到 list.it 应该如下所示。
List<Base<Class1>> list = new List<Base<Class1>>();
Class2<Class1> item = new Class2<Class1>();
list.Add(item);