通用基类的派生类型 [英] Derived type of generic base class

查看:78
本文介绍了通用基类的派生类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码.

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的子类型.为什么不起作用?

HeaderA is a subtype of Header and ItemA is a subtype of IItem. Why it doesn't work?

推荐答案

简而言之,您正在尝试使用称为 covariance 的概念,

In short, you're trying to use a concept called covariance, which is not supported in .NET generic classes, and not supported by default in interfaces.

如果要允许该类执行此操作,则可以在C#3或更高版本中使用out上下文关键字 ://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/generics/generic-interfaces"rel =" nofollow noreferrer"title ="通用接口(C#编程指南)-Microsoft Docs>通用接口:

If you want to allow the class to do this, you can specify it in C# 3 or later using the out contextual keyword on a generic interface:

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();
}

通过使用带有关键字的接口,您基本上是在告诉编译器,该接口的使用将永远不必了解有关

By using the interface with the keyword, you are basically telling the compiler that no usage of the interface will ever have to know more about the generic type than that it meets the constraints of the interface's generic type declaration (or that it's an object). As such, while you can now assign more derived generics to variables of the interface type, you can only deal with them as the interface type, never as any derived type.

查看全文

登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆