1、如何判断一个类型是否是泛类型的派生类?
比如:
int? i = 1;
bool compatible = typeof(Nullable<>).IsAssignableFrom(i.GetType());
此时 compatible 是false。
2、已知一个类型是泛类型,如何获取这个泛类型的类型参数?
比如:
int? i = 1;
Type t = i.GetType();
如何通过 "t" 获得类型 "int" ?
3、如何使用泛型基础类型的属性、方法对象对具体的泛型对象进行操作?
比如:
var t = typeof(Nullable<>);
var p = t.GetProperty("Value");
int? i = 1;
var v = p.GetValue(i);
这里执行最后一条的时候是不能通过的。
写了个扩展,暂时能满足别的需求,但对Nullable还是无奈:
public static class Extensions { public static bool IsCompatibleToGenericType(this Type source, Type genericType) { if(genericType.IsAssignableFrom(source)) { return true; } if(!genericType.IsGenericType) { return false; } if(genericType.IsClass && source.IsInterface) { return false; } if (!genericType.ContainsGenericParameters) { genericType = genericType.GetGenericTypeDefinition(); } if (genericType.IsInterface || source.IsInterface) { var interfaces = source.GetInterfaces(); foreach (var @interface in interfaces) { if (@interface.GetGenericTypeDefinition() == genericType) { return true; } } } else { while (source != typeof(object)) { if (source.IsGenericType) { if (source.GetGenericTypeDefinition() == genericType) { return true; } } source = source.BaseType; } } return false; } public static Type[] GetCompatibleGenericTypeParameterTypes(this Type source, Type genericType) { if(!genericType.IsGenericType || !source.IsCompatibleToGenericType(genericType)) { return new Type[0]; } if (!genericType.ContainsGenericParameters) { genericType = genericType.GetGenericTypeDefinition(); } if (genericType.IsInterface || source.IsInterface) { var interfaces = source.GetInterfaces(); foreach (var @interface in interfaces) { if (@interface.GetGenericTypeDefinition() == genericType) { return @interface.GetGenericArguments(); } } } else { while (source != typeof(object)) { if (source.IsGenericType) { if (source.GetGenericTypeDefinition() == genericType) { return source.GetGenericArguments(); } } source = source.BaseType; } } return new Type[0]; } }
@XiaoFaye: 谢谢。你的这个帖子已经是我通过对Type类型进行分析后的可控方案,但有个新的问题,如你贴的URL里所说,Nullable<>的类型,通过GetType后,返回的是泛类型参数的类型,如:
int? a;//用Nullable<int>定义是一样的
a.GetType()返回的是int
这里,我又应该怎么去判断当前传递进来的对象是否是Nullable<>兼容的呢?
谢谢。
@519740105: 你能给我写段代码说明你需要"判断当前传递进来的对象是否是Nullable<>兼容"的例子吗?
@Launcher: 没什么特殊的代码,就是下面这样:
int? i = 1;
Type type = i.GetType();
此时,获得的type是int而不是我要的Nullable<int>
@519740105: 既然这样,那我就你这段代码来说:
看你的第一句:int? i = 1,
既然你已经知道是 int? 类型了,那么你的下一行代码就可以这样写: Type type = typeof(int?);
因为我想知道的问题是,是什么原因造成你无法使用我给的这条语句,而必须使用 i.GetType() ?
@Launcher: 只是举例子,最后的这个变量i是要传递给一个函数,比如:
void Main()
{
int? i = 1;
Process(i);
}
void Porcess(object @object)
{
var type = @object.GetType();//type为:int
}
@519740105: 我们再来看你新给的这段代码中的这条语句: var type = @object.GetType();
请问,你需要这里的 type 变量用来做什么?
@Launcher: 这里只是一个例子,我只是问这里如何获取到类型 Nullable<int>。
@519740105:你这个弯儿没转过来,还是看这里: http://msdn.microsoft.com/en-us/library/ms366789.aspx,这里已经说的很明白了,你用 i.GetType() 是获取不到同 Nullable<> 类型有关联的信息的。因此我才问你必须得到 Nullable<int> 类型来做什么,因为你的需求可以通过其它方式来实现。
试过用反射吗?
简单的尝试了下,不可以达到目的,即便处理了,也将会很复杂了。
@519740105:
第一个应该是这样吧:
bool compatible = typeof(Nullable<int>).IsAssignableFrom(i.GetType());
这时候compatible 就是true了。
@XiaoFaye:
第二个i.GetType()我在Watch里面看到是Int32类型的。
@XiaoFaye: 换成List<>也类似。
@XiaoFaye: 关键是:此时我只想判断是否派生自Nullable<>(或者兼容),而且,int类型在运行过程中是不知道的。
@519740105:
你是说传过来给你的只是一个object,你要判断这个object是否派生自Nullable<>?
@XiaoFaye: 对。
他这样已经算是在用反射了```
你调试打断点,看typeof出来的类型信息里面就能看出来.