从模板类转换

时间:2013-11-04 11:48:14

标签: c# templates inheritance interface

我有一个班级MyClass<T>,其中T是某个界面:

class MyClass<T> where T: IMyInterface

我使用MyClass的一些实现编写了几个扩展IMyInterface的类,例如:

class MySecondClass : MyClass<MyInterfaceImplementation>

为什么不允许将MySecondClass实例分配给类型为MyClass<IMyInterface>的变量?

MyClass<IMyInterface> x = new MySecondClass()

当我添加隐式转换时:

public static implicit operator MyClass<IMyInterface>(MySecondClass c) {
    return c;
}

它开始工作。

3 个答案:

答案 0 :(得分:2)

要执行您想要的操作,您应该使用T关键字声明类型参数out是协变的(请参阅MSDN上的Covariance and Contravariance in Generics)。
您需要稍微修改一下代码,因为协方差和逆变只能在接口上定义:

interface IMyInterface { 
}

// note that this one is an interface now
interface IMyClass<out T> where T : IMyInterface { 
}

class MyInterfaceImplementation : IMyInterface { 
}

class MySecondClass : IMyClass<MyInterfaceImplementation> { 
}

class Program {
    static void Main(string[] args) {
        IMyClass<IMyInterface> x = new MySecondClass();
    }
}

答案 1 :(得分:1)

MyClass<IMyInterface>MySecondClass两个不同的类和编译器不能隐式地将一种类型的对象转换为另一种类型。

而且这两个类只有System.Object作为公共基类

答案 2 :(得分:0)

这是因为泛型类(c ++语言中的模板)和设计的性质。

例如:

MyClass<object> o = new MyClass<string>();

也将无法编译。通用类只是因为它们的泛型类型而不是彼此的后代。它们实际上是不同的类,在面向对象的意义上彼此没有关系。