c# - 在不知道类型的情况下返回泛​​型

标签 c# generics inheritance types factory

我有一个类在其通用类型参数中接受某个对象类型的实例。布局是这样的:

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-variantout指定类型参数是协变的:

public interface IHandler<out T> where T : BaseClass 
{
}

具有协变类型参数的接口(interface)使其方法能够返回比类型参数指定的派生类型更多的派生类型

它会起作用的。更多信息是here

关于c# - 在不知道类型的情况下返回泛​​型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12625209/

相关文章:

java - Spring 和继承的线程安全

c# - Android网络可达性(离线模式)?

c# - 为什么我不能使用 XmlSerializer 序列化只读字段?

c# - 用于上传数据的Web服务 : security considerations

java - Java 中泛型类型和使用接口(interface)作为类型的区别

swift - 尝试在闭包中使用泛型类型时出现意外的编译器错误

c# - 我应该在表格关闭时取消注册事件吗?

java - 声明接口(interface)方法仅允许实现的类

java - Java中自动加载特定父类(super class)的子类的工厂类?

c++ - 如何在派生类构造函数之后强制调用基类函数?