C# 获取ICollection的类型参数<;T>;实现类
我正在.net中编写一个小型序列化库。目标是替换XmlSerialize,但更易于配置,并且不会将模型与属性弄乱 我面临的问题是,我需要遍历模型期间找到的每个C# 获取ICollection的类型参数<;T>;实现类,c#,.net,generics,reflection,C#,.net,Generics,Reflection,我正在.net中编写一个小型序列化库。目标是替换XmlSerialize,但更易于配置,并且不会将模型与属性弄乱 我面临的问题是,我需要遍历模型期间找到的每个ICollection的类型。 天真的做法是: var theType=myModel.GetType().GetGenericArguments()[0]; 但是对于从具有特定T的ICollection派生的类来说,它没有帮助 public class MyClass:A,ICollection<B>{} 我认为下面的电
ICollection
的类型。
天真的做法是:
var theType=myModel.GetType().GetGenericArguments()[0];
但是对于从具有特定T的ICollection
派生的类来说,它没有帮助
public class MyClass:A,ICollection<B>{}
我认为下面的电话就是问题所在
.Select(i => i.GetGenericTypeDefinition())
使用已定义的泛型参数获取封闭的泛型类型,然后获取其泛型定义,它是开放的,并且只知道T
。也许您还需要更改FirstOrDefault
调用,我不确定关闭类型是否等于ICollection
这就是您需要的:
那么,
class MyDictionary: IDictionary<string, decimal>
{
...
}
那叫
Type[] types = typeof(MyDictionary).GetClosingArguments(typeof(IDictionary<,>));
Type[]types=typeof(MyDictionary);
从评论中,您似乎需要找出如何过滤集合,使其仅包含ICollection。您可以通过以下方式实现该目标:
var iCollectionInterfaces =
from i in o.GetType().GetInterfaces()
where i.IsGenericType
&& i.GetGenericTypeDefinition() == typeof(IColection<>)
select i;
var iCollectionInterfaces=
从i到o.GetType().GetInterfaces()
其中i.IsGenericType
&&i.GetGenericTypeDefinition()==typeof(ICollection)
选择i;
然后,您可以迭代集合,并对每个类型参数执行任何需要的操作
//same type might implement ICollection<T> more than once
foreach(var collection in iCollectionInterfaces) {
//More than one is invalid for ICollection<T>
var T = collection.GetGenericArguments().Single();
//do what ever you need
}
//同一类型可能多次实现ICollection
foreach(iCollectionInterfaces中的变量集合){
//多个对ICollection无效
var T=collection.GetGenericArguments().Single();
//你需要什么就做什么
}
当然,如果你想让它更通用。Ie要支持具有多个类型参数的接口/类型,您需要删除对
Single
的调用,并替换为类型参数的迭代非常感谢,它提供了类型。但是我的问题更多的是对i收集实现的过滤。@Enton你读过你自己的问题了吗?过滤没有任何意义。我的问题不是“为所有实现的接口获取所有类型参数”,而是“为一个特定接口的实现获取类型参数”@Enton我觉得过滤不是重点……很抱歉。不过,看看我的建议。现在它更接近你需要的了。演示如何筛选到感兴趣的接口。Thanx,仅为完整性起见,一个。其中(i=>i.IsGenericType)
有助于防止i.GetGenericTypeDefinition()
上的错误(如果它不是泛型类型)。
Type[] types = typeof(IDictionary<,>).GetClosingArguments<MyDictionary>();
if (types != null)
{
foreach (Type t in types)
Console.WriteLine(t.Name);
}
public static Type[] GetClosingArguments(this Type type, Type baseGenericType)
{
Type iType = type.GetInterfaces()
.FirstOrDefault(i => i.IsGenericType &&
i.GetGenericTypeDefinition() == baseGenericType);
if (iType == null)
return null;
else
return iType.GetGenericArguments();
}
Type[] types = typeof(MyDictionary).GetClosingArguments(typeof(IDictionary<,>));
var iCollectionInterfaces =
from i in o.GetType().GetInterfaces()
where i.IsGenericType
&& i.GetGenericTypeDefinition() == typeof(IColection<>)
select i;
//same type might implement ICollection<T> more than once
foreach(var collection in iCollectionInterfaces) {
//More than one is invalid for ICollection<T>
var T = collection.GetGenericArguments().Single();
//do what ever you need
}