Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 获取ICollection的类型参数<;T>;实现类_C#_.net_Generics_Reflection - Fatal编程技术网

C# 获取ICollection的类型参数<;T>;实现类

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>{} 我认为下面的电

我正在.net中编写一个小型序列化库。目标是替换XmlSerialize,但更易于配置,并且不会将模型与属性弄乱

我面临的问题是,我需要遍历模型期间找到的每个
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
}