无法将源类型转换为目标类型编译错误

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,我不知道为什么会出现编译错误。请帮助我理解我做错了什么。

谢谢,埃森

Dav*_*rno 5

这是由于泛型有一个相当复杂的特性,称为方差

类是不变的,这意味着如果您声明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它自己。不过,使用协变(和逆变)存在风险,这就是为什么泛型类默认是不变的。