我有一个类在其通用类型参数中接受某个对象类型的实例。布局是这样的:
public abstract BaseClass { ... }
public DiamondClass : BaseClass { ... }
public SilverClass : BaseClass { ... }
public Handler<T> where T : BaseClass { ... }
我希望能够创建一个方法来返回 Handler<DiamondClass>
的实例或 Handler<BaseClass>
没有在输入时定义类型。我已经尝试了这些方法:
public Handler<BaseClass> GetHandler(HandlerType type)
{
switch(type)
{
case HandlerType.Diamond: return new Handler<DiamondClass>();
case HandlerType.Silver: return new Handler<SilverClass>();
default: throw new InvalidOperationException("...");
}
}
但这行不通,因为显然 Handler<DiamondClass>
不会隐式转换为 Handler<BaseClass>
.我可以这样指定它:
public Handler<T> GetHandler<T>(HandlerType type) where T : BaseClass
{
switch(type)
{
case HandlerType.Diamond: return (Handler<T>)new Handler<DiamondClass>();
case HandlerType.Silver: return (Handler<T>)new Handler<SilverClass>();
default: throw new InvalidOperationException("...");
}
}
但现在我需要调用GetHandler<DiamondClass>
或 GetHandler<BaseClass>
.这违背了在不知道类型的情况下使用基于枚举返回正确处理程序的方法的目的。我希望我可以定义一个 Type
对象并传递它,这样:
Type objType = typeof(DiamondClass);
var handler = Handler<objType>();
但显然 C# 不允许这种愚蠢行为。我已经用几种不同的方式解决了这个问题,我想有办法做到这一点,但我很困惑。
(实际上我确实通过返回一个 dynamic
对象来实现它,但我想尽可能避免它,因为它会失去任何类型安全和 Intellisense 支持。)
最佳答案
这就是 co-variance 发挥作用的地方,协变和逆变仅适用于接口(interface)和委托(delegate),因此,要解决您的问题,只需定义一个新接口(interface) IHandler
作为 co-variant 与 out
指定类型参数是协变的:
public interface IHandler<out T> where T : BaseClass
{
}
具有协变类型参数的接口(interface)使其方法能够返回比类型参数指定的派生类型更多的派生类型
它会起作用的。更多信息是here
关于c# - 在不知道类型的情况下返回泛型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12625209/