强制转换为带有反射的泛型接口

本文关键字:反射的 泛型接口 转换 | 更新日期: 2023-09-27 18:18:00

我已经简化了代码,但基本上这段代码运行在循环上,类型来自反射。这里唯一的常数是IWorker<T>接口。

我需要访问IWorker的属性,但我不能转换它,因为argType不被编译器接受,有什么想法吗?

(我可以在dynamic中这样做,但我希望有一个替代方案来防止未来由于重构而导致的bug)

Type argType = @interface.GetGenericArguments().First();
var worker = (IWorker<argType>)FormatterServices.GetUninitializedObject(MyType);

MyType源自IWorker<T>,其中T在编译时是未知的。

强制转换为带有反射的泛型接口

如果可能的话,您应该使该方法具有泛型。这是维护编译时类型安全的唯一方法。如果这不是一个选项,并且该方法必须直接接受Type参数,那么根据定义,您最终使用的任何解决方案都将无法维护静态类型。

public static IWorker<T> Foo<T>()
{
    return (IWorker<T>)FormatterServices.GetUninitializedObject(typeof(T));
}

你可以这样调用它:

IWorker<ArgType> worker = Foo<ArgType>();

恐怕你不能那样做。泛型类型参数必须在编译时已知。类型强制转换也必须在编译时知道。这里有两个选项:

  1. 使用泛型方法(参见Servy的回答)

  2. 创建一个非泛型接口,并使IWorker<T>从它继承:

    public interface IWorker 
    { 
        string MyProperty { get; }
    }
    public interface IWorker<T> : IWorker
    {
        ...
    }
    

    那么你可以这样使用:

    var worker = (IWorker)FormatterServices.GetUninitializedObject(MyType);
    worker.MyProperty = "Somwthing";