使用 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.BaseType
和MyView<>
,因为当前类型不是泛型,但他的父类型可以。类似于下面的代码
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;
}
我有一个摘要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.BaseType
和MyView<>
,因为当前类型不是泛型,但他的父类型可以。类似于下面的代码
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;
}