通过反射实例化泛型类型

时间:2012-03-25 11:38:56

标签: c# generics

让我们假设我已经通过Activator.CreateInstance实例化了泛型类型。如果我在编译时没有T(但我把它作为Type实例),有没有办法将它强制转换为ISomeInterface?

以下是一个示例:

public static IPropertyAssertions<T> ShouldHave<T>(this T subject)
{
    var implementedInterfaces = subject.GetType().GetInterfaces();
    foreach (var interfaceType in implementedInterfaces)
    {
        if (!interfaceType.IsGenericType)
            continue;

        var genericType = interfaceType.GetGenericTypeDefinition();
        if (genericType == typeof(IEnumerable<>))
        {
            var genericTypeArg = genericType.GetGenericArguments()[0];

            var collectionPropertyAssertionsType = typeof (CollectionPropertyAssertions<>);

            Type makeme = collectionPropertyAssertionsType.MakeGenericType(genericTypeArg);

            return (IPropertyAssertions<ToDo: specify argument type here>) Activator.CreateInstance(makeme);
        }
    }

    ...
}

所以我有可以在IEnumerable<T>上调用的扩展方法。在这种情况下,我想不返回CollectionPropertyAssertions<IEnumerable<T>>而是返回CollectionPropertyAssertions<T>,其中T是枚举元素的类型。

1 个答案:

答案 0 :(得分:5)

你将无法施放,不 - 你必须强制转换为在编译时已知的类型......一半是能够使用该类型的特定成员。

您可能需要考虑的一些情况:

  • 如果要调用需要ISomeInterface<T>作为参数的通用方法,可以通过反射调用此方法或使用动态类型
  • 如果你想调用那些不依赖T的成员,你可能要考虑创建一个ISomeInterface<T>扩展的非泛型基接口 - 然后你就可以转换为非-generic interface。

如果这不包括您要执行的操作,请提供更多详细信息。

编辑:在这种情况下,您 知道T,因为您使用的是通用方法 - 所以您只需要转换为IPropertyAssertions<T>