Ese*_*sen 6 c# generics type-conversion
我有这个简单的课程
public class Program
{
private static void Main(string[] args)
{
ClassB<ClassA> objA = new ClassB<ClassA>();
ClassB<ITestA<MyDTO>> objB = new ClassB<ClassA>();
}
}
public class ClassB<T>
{
///some code here
}
public interface ITestA<T>
{
///some code here
}
public class MyDTO
{
///some code here
}
public class ClassA : ITestA<MyDTO>
{
///some code
}
Run Code Online (Sandbox Code Playgroud)
这行代码
ClassB<ITestA<MyDTO>> objB = new ClassB<ClassA>();
Run Code Online (Sandbox Code Playgroud)
给出编译错误
Cannot implicitly convert type 'ClassB<ClassA>' to 'ClassB<ITestA<MyDTO>>
Run Code Online (Sandbox Code Playgroud)
由于 ClassA 实现了 ITestA,我不知道为什么会出现编译错误。请帮助我理解我做错了什么。
谢谢,埃森
这是由于泛型有一个相当复杂的特性,称为方差。
类是不变的,这意味着如果您声明ClassB<T>
,则在创建实例时:
ClassB<T1> obj = new ClassB<T2>
Run Code Online (Sandbox Code Playgroud)
那么T1
必须与 完全相同的类T2
。
您可以使用接口来解决这个问题,例如将代码更改为以下内容,它将编译:
...
public class Program
{
private static void Main(string[] args)
{
ClassB<ClassA> objA = new ClassB<ClassA>();
IClassB<ITestA<MyDTO>> objB = new ClassB<ClassA>();
}
}
public interface IClassB<out T> // <- note the out before T
{
//some code here
}
public class ClassB<T> : IClassB<T>
{
//some code here
}
...
Run Code Online (Sandbox Code Playgroud)
在本例中,IClassB
被声明为协变,这意味着它可以处理被赋予 的派生类T
,而不是需要T
它自己。不过,使用协变(和逆变)存在风险,这就是为什么泛型类默认是不变的。