c# - 使用泛型转换为基类

标签 c# generics

我似乎无法理解 C# 中的泛型。

基本上我有一个名为 ConfigWorker 的基类和一堆子类,它们都应该使用它们自己的派生自 BaseConfig 的配置类.

我想使用的 ConfigWorker 类应该在运行时动态确定,给定类的名称作为参数。

我可以根据它的名称实例化子类,但无论我尝试什么,我都无法转换为合理的基类。

这是我的代码:

namespace DocumentHandler
{

    public class BaseConfig
    {
    }

    public class ConfigWorker<T> where T : BaseConfig
    {
        public virtual void Work(T options)
        {

        }

    }

    public class Worker1 : ConfigWorker<Worker1.Config>
    {
        public class Config : BaseConfig
        {
            public string test = "";
        }

        public override void Work(Config options)
        {
            //do something
        }
    }

    public class Worker2 : ConfigWorker<Worker2.Config>
    {
        public class Config : BaseConfig
        {
            public string test = "";
        }

        public override void Work(Config options)
        {
            //do something else
        }
    }

    public class Test
    {
        public static BaseConfig config; 

        public static void test()
        {
            (Activator
                .CreateInstance(Type.GetType("DocumentHandler.Worker2")) 
                as ConfigWorker<BaseConfig>)
            .Work(config);
        }
    }
}

关键是

(Activator
    .CreateInstance(Type.GetType("DocumentHandler.Worker2")) 
    as ConfigWorker<BaseConfig>)
.Work(config);

类型转换到ConfigWorker<BaseConfig>返回 null,因为无法执行转换。

尝试简单地转换为 ConfigWorker不编译,因为缺少类型参数。

还有什么我可以尝试的吗? CreateInstance显然只是返回一个对象,我需要转换它才能调用 Work方法

感谢任何帮助。

最佳答案

Worker2 的实例不是 ConfigWorker<BaseConfig> !这是一个ConfigWorker<Worker2.Config> .这是两种完全不同的类型。通用类是不变的。只有接口(interface)和委托(delegate)可以协变或逆变。

在您的示例中,ConfigWorkerT 中甚至是反变 ,意味着您使用 T作为方法的输入参数的类型。所以你的尝试实际上是危险的。

想象一下你的行会起作用:你得到一个类型为 ConfigWorker<BaseConfig> 的变量, 所以你可以依赖这个实例有一个方法 Work()这需要 BaseConfig (或从中派生出的东西)作为参数。所以没有什么能阻止你这样调用它

worker.Work(new Worker1.Config());

编译正常。但是等一下!你的台词不是说worker吗?是 Worker2Worker2实例只能处理 Worker2.Config争论!
您以这种方式完全失去了类型安全性(好吧,如果允许的话,您会这样做)。

您的类(class)设计存在缺陷。

关于c# - 使用泛型转换为基类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57802708/

相关文章:

c# - Windows Phone 8 中的弹出窗口

generics - 如何在Kotlin中的重载运算符上指定泛型类型?

c# - 如何使用 SWIG 将 IEnumerable 作为参数的 C++ 委托(delegate)从 C# 创建传递?

c# - 如何强制我的 C# Winforms 程序在任何计算机上以管理员身份运行?

scala - 是否可以在 Scala 中指定对泛型类型 τ 的约束,使得 τ < : σ ∧ τ ≠ σ?

C# 泛型函数

Java - ArrayList 和 ArrayList<Object> 是两个不同的类吗?

java - 明确指定通配符的上限时有区别吗?

c# - 我可以在 x86 机器上测试我的应用程序的 x64 版本吗?

c# - NavigationService 提示从未附加到任何 View 的类执行 "FileNotFound"