使用 GetType 获取通用类型

Get generic type using GetType

我有一个摘要class

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

和派生的 class:

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<>) 比较部分。我意识到从该检查中返回的唯一类型是抽象 class.

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

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

您的代码仅获取特定 class、MyView<TPresenter> 的类型,这就是您获取结果的原因,因为您仅获取与该类型相同的类型; 不能返回任何其他内容。

嗯,你应该比较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();

不幸的是,这并不是微不足道的,但也不是非常困难。您需要做的是枚举给定类型的基本类型,并检查它们中的每一个是否都是 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;
}