[英]How to get generic argument types of generic type from derived type in c#
Supose i have:假设我有:
class MyBase<T1, T2>{}
class MyConcreteBase<T2> : MyBase<ConcreteType1, T2>{}
class MyConcrete1 : MyConcreteBase<ConcreteType2>{}
class MyConcrete2 : MyBase<ConcreteType1, ConcreteType2>{}
How do i get types of T1
and T2
if i have instance of MyConcrete1
or MyConcrete2
or MyConcreteBase
or any other instance of type derived from MyBase<T1, T2>
如果我有
MyConcrete1
或MyConcrete2
或MyConcreteBase
的实例或派生自MyBase<T1, T2>
的任何其他类型实例,我如何获得T1
和T2
的类型
The way i do it now is i'm "getting up" by inheritance chain using .GetType().BaseType
while BaseType.Name.StartsWith("MyBase")
and then using .GetGenericArguments()
我现在这样做的方式是我通过 inheritance 链“起床”,使用
.GetType().BaseType
而BaseType.Name.StartsWith("MyBase")
然后使用.GetGenericArguments()
It is working, but i'm not satisfied with it, especially .StartsWith("MyBase")
part.它正在工作,但我对此并不满意,尤其是
.StartsWith("MyBase")
部分。
Anyone have other suggestions?有人有其他建议吗?
You can walk up the inheritance hierarchy and look for a GenericType, which is constructed from BaseType<,>
.您可以向上走 inheritance 层次结构并查找由
BaseType<,>
构造的 GenericType。 Try:尝试:
var type = c.GetType();
Type baseType = type;
while(null != (baseType = baseType.BaseType))
{
if (baseType.IsGenericType)
{
var generic = baseType.GetGenericTypeDefinition();
if (generic == typeof(MyBase<,>))
{
var genericTypes = baseType.GetGenericArguments();
// genericTypes has the type argument used to construct baseType.
break;
}
}
}
Yeah, don't use string parsing.是的,不要使用字符串解析。 You can simply use
BaseType.IsAssignableFrom(typeof(MyBase<,>))
(might have to reverse the BaseType
and MyBase<,>
-- I always get that confused).您可以简单地使用
BaseType.IsAssignableFrom(typeof(MyBase<,>))
(可能必须颠倒BaseType
和MyBase<,>
- 我总是感到困惑)。
It might also be easier to expose the types as properties in your base class, eg:将类型公开为基础 class 中的属性也可能更容易,例如:
public Type T1_Type { get { return typeof(T1); } }
public Type T2_Type { get { return typeof(T2); } }
I do have to ask, why do you need to extract these type parameters?我不得不问,为什么需要提取这些类型参数? This is a code smell to me.
这对我来说是一种代码味道。
EDIT: I should add that you can't use IsAssignableFrom
as is for generics.编辑:我应该补充一点,你不能像
IsAssignableFrom
一样使用 IsAssignableFrom。 Check out this answer for a full solution: How To Detect If Type is Another Generic Type查看此答案以获取完整解决方案: 如何检测类型是否为另一种通用类型
Would be good if you would tell us a bit more about what you want to achive.如果您能告诉我们更多关于您想要实现的目标,那就太好了。 Guessing what you idea is, I would say: Just walk the complete inheritance chain as long as
BaseType
is not null
.猜猜你的想法是什么,我想说:只要
BaseType
不是null
,就走完整的 inheritance 链。 And then check for each type if it's generic and if yes, call GetGenericArguments
.然后检查每种类型是否是通用的,如果是,请调用
GetGenericArguments
。 Should be a matter of a few predicates and one or two LINQ expressions.应该是几个谓词和一两个 LINQ 表达式的问题。
I can't think of anything clever, so I'd probably just do this:我想不出任何聪明的东西,所以我可能会这样做:
class MyBase<T1, T2> {
protected Type GetT1() { return typeof(T1); }
protected Type GetT2() { return typeof(T2); }
}
Here is a function that will accept any type (assuming it has a base class with generic parameters) and return the types of that instance's base class's generic parameters:这是一个 function 将接受任何类型(假设它具有带有泛型参数的基本 class)并返回该实例的基类的泛型参数的类型:
public Type[] BaseGenericTypes<T>(T instance)
{
Type instanceType = instance.GetType();
Type objectType = new object().GetType();
while (instanceType.BaseType != objectType)
{
instanceType = instanceType.BaseType;
}
return instanceType.GetGenericArguments();
}
The nice thing about this method is you don't need to know anything about the base class or any of its subsequent derived classes.这种方法的好处是您不需要知道任何关于基础 class 或其任何后续派生类的信息。
Do you mean: Type.GetGenericArguments Method ?你的意思是: Type.GetGenericArguments 方法?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.