如何向上转换泛型类型参数

Sex*_*yMF 2 c# generics

当我在这种情况下使用反射时,创建的类型可以是许多泛型类型。

BaseStepHandler<BaseStepDataModel> activator = (BaseStepHandler<BaseStepDataModel>)Activator.CreateInstance(....);
Run Code Online (Sandbox Code Playgroud)

创建的实例可以是 BaseStepDataModel 的所有子项。

BaseStepHandler<OneDataModel>
OR
BaseStepHandler<TwoDataModel>

OneDataModel 和 TwoDataModel 正在扩展 BaseStepDataModel。

这是我得到的例外:

无法将类型为“....GlobalOnBoardingStepOneHandler”的对象转换为类型“....BaseStepHandler`1[....BaseStepDataModel]”。

这是 GlobalOnBoardingStepOneHandler 的声明。

public class GlobalOnBoardingStepOneHandler : BaseStepHandler<GlobalOnBoardingStepOneDataModel>{}
Run Code Online (Sandbox Code Playgroud)

Mat*_*zer 5

这里的问题是您期望具体类型泛型参数的逆变 协方差

基本上,您永远不会使用具体类型实现目标,但有一个解决方法。

您可以像这样设计一个标记界面:

public interface IBaseStepHandler<out T> // "out" marks T as covariant
   where T : BaseDataModel // Do you have a model base type? ;)
{
     // Declare members here
}
Run Code Online (Sandbox Code Playgroud)

在我说“在此处声明成员”的地方,只需声明这些成员是您的具体基类的一部分(我说的是“BaseStepHandler”)。

之后,在您的基类BaseStepHandler 中实现此接口。

现在,你可以做你想做的:

IBaseStepHandler<BaseDataModel> some = new WhateverBaseStepHandlerClass(); 

// This is possible because T generic parameter is covariant and it can be casted to `BaseDataModel`, or if you don't provide a `T` generic parameter constraint, you could cast it to `IBaseStepHandler<object>` too!
Run Code Online (Sandbox Code Playgroud)

要了解有关协方差的更多信息,请访问以下链接:http : //msdn.microsoft.com/en-us/library/ee207183.aspx