无法将源类型转换为目标类型编译错误
Cannot convert source type to target type compilation error
我有这个简单的class
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
}
这行代码
ClassB<ITestA<MyDTO>> objB = new ClassB<ClassA>();
出现编译错误
Cannot implicitly convert type 'ClassB<ClassA>' to 'ClassB<ITestA<MyDTO>>
既然ClassA实现了ITestA,不知道为什么会报编译错误。请帮助我了解我做错了什么。
谢谢,
埃森
这是由于泛型的一个相当复杂的特性,称为 variance。
类是不变的,也就是说如果你声明了ClassB<T>
,那么在创建实例的时候:
ClassB<T1> obj = new ClassB<T2>
那么 T1
必须与 T2
完全相同 class。
您可以使用接口来解决这个问题,例如,将您的代码更改为以下内容,它会编译:
...
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
}
...
在这种情况下,IClassB
被声明为协变的,这意味着它可以处理 T
的派生 class,而不需要 T
本身.但是,使用协变(和逆变)存在风险,这就是为什么泛型 classes 在默认情况下是不变的。
我有这个简单的class
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
}
这行代码
ClassB<ITestA<MyDTO>> objB = new ClassB<ClassA>();
出现编译错误
Cannot implicitly convert type 'ClassB<ClassA>' to 'ClassB<ITestA<MyDTO>>
既然ClassA实现了ITestA,不知道为什么会报编译错误。请帮助我了解我做错了什么。
谢谢, 埃森
这是由于泛型的一个相当复杂的特性,称为 variance。
类是不变的,也就是说如果你声明了ClassB<T>
,那么在创建实例的时候:
ClassB<T1> obj = new ClassB<T2>
那么 T1
必须与 T2
完全相同 class。
您可以使用接口来解决这个问题,例如,将您的代码更改为以下内容,它会编译:
...
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
}
...
在这种情况下,IClassB
被声明为协变的,这意味着它可以处理 T
的派生 class,而不需要 T
本身.但是,使用协变(和逆变)存在风险,这就是为什么泛型 classes 在默认情况下是不变的。