使用GetType获取泛型类型

时间:2017-08-01 18:41:37

标签: c# generics gettype

我有一个抽象类

public abstract class MyView<TPresenter> : UserControl, IMyView<TPresenter> where TPresenter : IPresenter
{
}

和派生类:

public partial class CreateUserViewControl : MyView<CreateUserPresenter>
{
}

现在我想从程序集中的所有类型中获取CreateUserViewControl的泛型类型(名称),如下所示:

var genericType = Assembly.GetExecutingAssembly().GetTypes().Where(t => t == typeof(MyView<>)).First().GetGenericArguments().First();

我希望genericType包含CreateUserViewControl类型,但它包含TPresenter

我做错了什么以及如何获得CreateUserViewControl类型?

编辑:

好的,经过对我自己的问题的简短回顾,我看到了原因所在。 它是t == typeof(MyView<>)比较部分。我意识到从该检查中返回的唯一类型是抽象类。

我想要做的是检查是否typeof(MyView<>).IsAssignableFrom(t),但不幸的是,这也不起作用。

3 个答案:

答案 0 :(得分:1)

CreateUserViewControl 不是通用的,因此没有任何通用参数。它继承自泛型类,它继承的泛型类具有CreateUserViewControl的泛型参数。

您的代码只获取一个特定类MyView<TPresenter>的类型,这是您获得结果的类型,因为您只获得与该类型相同的类型;没有其他可以返回。

答案 1 :(得分:1)

那么,您应该比较t.BaseTypeMyView<>,因为当前类型不是通用类型,但他的父类可以。它类似于下面的代码

    var genericBaseType = Assembly.GetExecutingAssembly().GetTypes().Where(t => t.BaseType != null && t.BaseType.IsGenericType && t.BaseType.GetGenericTypeDefinition() == typeof(MyView<>)).First();
    var genericArgument = genericBaseType.BaseType.GetGenericArguments().First();

答案 2 :(得分:0)

不幸的是,这并非完全无足轻重,但它并不是非常困难。你要做的是枚举给定类型的基类型,并检查它们是否都是MyView<T>的具体版本。

这是一个帮助者,它会枚举给定类型的基本类型。

internal static class TypeEx
{
    public static IEnumerable<Type> GetBaseTypes( this Type type )
    {
        yield return type;

        while( type.BaseType != null )
        {
            type = type.BaseType;
            yield return type;
        }
    }
}

现在您可以创建另一种方法来检查类型是否继承自MyView

public static bool InheritsMyView( Type type, out Type genericArgument )
{
    foreach( var baseType in type.GetBaseTypes() )
    {
        if( !baseType.IsGenericType ) continue;
        if( baseType.GetGenericTypeDefinition() != typeof( MyView<> ) ) continue;
        genericArgument = baseType.GetGenericArguments()[0];
        return true;
    }

    genericArgument = null;
    return false;
}