繁体   English   中英

使用Activator.CreateInstance进行通用类型转换

[英]Generic type casting using Activator.CreateInstance

我有一个界面

public interface ISomething<TValue>
    where TValue : IConvertible
{
    ...
}

然后,我还有一些具有泛型方法的非泛型类:

public class Provider
{
    public static void RegisterType<TValue>(ISomething<TValue> instance)
        where TValue : IConvertible
    {
        ...
    }
}

直到我要在我的特定程序集中自动注册所有适用的类型之前,这似乎还不错。

public void InitializeApp()
{
    foreach(Type t in Assembly.GetExecutingAssembly().GetTypes().Where(t => typeof(ISomething<>).IsAssignableFrom(T)))
    {
        // ERROR
        Provider.RegisterType(Activator.CreateInstance(t));
    }
}

此代码导致错误,因为无法从用法中推断出参数类型。 我要么

  1. 使用我的通用方法RegisterType提供显式的通用类型(由于代码的动态性质,我不认为可以做到这一点)或
  2. 将结果从Activator.CreateInstance为适当的类型,以便可以从用法中推断出参数类型

但是我也不知道该怎么办? 也许还有我不知道的第三种选择。

泛型是编译时的功能,这意味着必须在编译时知道泛型类型。 因此,当您仅在运行时知道类型时,就不能使用RegisterType方法,因为编译器无法推断出通用参数。

您在这里有几个选择。 您可以使用反射来调用正确版本的RegisterType (如注释中所建议),或者可以创建RegisterType的其他非泛型重载,该重载接受对象并从中找出执行时类型。

对于前者,它看起来像这样:

public void InitializeApp()
{
    foreach(Type t in Assembly.GetExecutingAssembly().GetTypes().Where(t => typeof(ISomething<>).IsAssignableFrom(T)))
    {
        var methodInfo = typeof( Provider ).GetMethod( "RegisterType", BindingFlags.Static );
        var registerTypeMethod = methodInfo.MakeGenericMethod( t );
        registerTypeMethod.Invoke( null, new[] { Activator.CreateInstance(t) } );
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM