如何通过反射获取集合中包含的类型

时间:2009-12-14 11:25:35

标签: c# reflection collections

在我的代码的某些部分,我传递了T类型的对象集合。除了命令IEnumerable之外,我不知道我将通过哪个具体的收集。

在运行时,我需要找出T的类型(例如System.DoubleSystem.String等...)。

有没有办法找到它?

更新:我应该澄清一下我工作的背景(Linq提供商)。

我的函数有如下签名,我将集合的类型作为参数:

string GetSymbolForType(Type collectionType)
{

}

是否有任何方法可以从collectionType获取包含的对象类型?

7 个答案:

答案 0 :(得分:19)

来自Matt Warren's Blog

internal static class TypeSystem {
    internal static Type GetElementType(Type seqType) {
        Type ienum = FindIEnumerable(seqType);
        if (ienum == null) return seqType;
        return ienum.GetGenericArguments()[0];
    }
    private static Type FindIEnumerable(Type seqType) {
        if (seqType == null || seqType == typeof(string))
            return null;
        if (seqType.IsArray)
            return typeof(IEnumerable<>).MakeGenericType(seqType.GetElementType());
        if (seqType.IsGenericType) {
            foreach (Type arg in seqType.GetGenericArguments()) {
                Type ienum = typeof(IEnumerable<>).MakeGenericType(arg);
                if (ienum.IsAssignableFrom(seqType)) {
                    return ienum;
                }
            }
        }
        Type[] ifaces = seqType.GetInterfaces();
        if (ifaces != null && ifaces.Length > 0) {
            foreach (Type iface in ifaces) {
                Type ienum = FindIEnumerable(iface);
                if (ienum != null) return ienum;
            }
        }
        if (seqType.BaseType != null && seqType.BaseType != typeof(object)) {
            return FindIEnumerable(seqType.BaseType);
        }
        return null;
    }
}

答案 1 :(得分:9)

myCollection.GetType().GetGenericArguments() 

将返回args类型的数组。

答案 2 :(得分:0)

Type t = null
foreach(object o in list)
{
o.GetType();
}

将为您提供对象的类型。

然后你应该测试你想要的类型:

if(t == typeof(myClass))
{
dosomething();
}
else if (t == typeof(myOtherClass))
{
dosomethingelse();
}

答案 3 :(得分:0)

你不能只使用t.GetType()来做到这一点。

答案 4 :(得分:0)

为什么不直接实施IEnumerable<T>? EG:

public void MyFunc<T>(IEnumerable<T> objects)

除此之外,您最好使用is.GetType检查每个对象的类型,而不是尝试从容器本身进行处理。

如果这不是一个选项,你真的需要知道基本容器的类型,你基本上必须使用is来检查它实现的接口(EG:IList<int>等) 。赔率是你的数组的类型将是一个泛型,这意味着尝试从它的名称返回到它的数据类型将是非常混乱。

答案 5 :(得分:0)

我在这里已经很晚了,但不应该做这件事:

  public static bool ThatCollectionIsOfType<T>(IEnumerable<T> collection, Type got)
  {
         if (**typeof(T)** == got) //this line should be good to go...
         {
            return true;
         }

   }

答案 6 :(得分:0)

我使用动态很多,这是一个不时出现的问题。

马特戴维斯钉了它,但你需要索引:)

public static void PopulateChildCollection<T>(T currentObject, string singlePropertyName)
{
  dynamic currentObjectCollection = ReflectionTools.GetPropertyValue(currentObject, singlePropertyName);
  Type collectionType = currentObjectCollection.GetType().GetGenericArguments()[0];

类型将是您所期望的,它是集合中包含的对象的类型,而不是它周围的任何泛型类型。