Derived type of generic base class

99封情书 提交于 2019-12-30 07:11:09

问题


I have the following code.

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

The last line cannot be compiled.

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

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


回答1:


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.

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.

The out keyword is not acceptable for class definitions; you cannot force usages of Header<T> to be covariant.



来源:https://stackoverflow.com/questions/12431246/derived-type-of-generic-base-class

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!