繁体   English   中英

派生类型的通用基类

[英]Derived type of generic base class

我有以下代码。

class Header<T> where T: IItem { }
class HeaderA : Header<ItemA> { } 
class HeaderB : Header<ItemB> { } 

interface IItem { }
class ItemA : IItem { }
class ItemB : IItem { }

Header<IItem> h = new HeaderA();

最后一行无法编译。

 Cannot implicitly convert type 'UserQuery.HeaderA' to 'UserQuery.Header<UserQuery.IItem>' 

HeaderA是Header的子类型,ItemA是IItem的子类型。 为什么它不起作用?

简而言之,您尝试使用称为协方差的概念,这在.NET泛型类中不受支持,并且在接口中默认不受支持。

如果要允许类执行此操作,可以使用通用接口上的out contextual关键字在C#3或更高版本中指定它:

interface IHeader<out T> where T : IItem { }
class Header<T>: IHeader<T> where T:IItem { }
class HeaderA : Header<ItemA> { }
class HeaderB : Header<ItemB> { }

interface IItem { }
class ItemA : IItem { }
class ItemB : IItem { }

public void Foo()
{
    //now this works; notice the use of the interface instead of the base class.
    IHeader<IItem> h = new HeaderA();
}

通过使用带有关键字的接口,您基本上告诉编译器,对接口的使用不必了解泛型类型,而不是它满足接口的泛型类型声明(或它是一个对象)的约束。 因此,虽然您现在可以将更多派生泛型分配给接口类型的变量,但您只能将它们作为接口类型处理,而不是任何派生类型。

对于类定义, out关键字是不可接受的; 你不能强迫Header<T>用法是协变的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM