简体   繁体   English

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

[英]How to get the type contained in a collection through reflection

In some part of my code I am passed a collection of objects of type T . 在我的代码的某些部分,我传递了T类型的对象集合。 I don't know which concrete colletion I will be passed, other than it impements IEnumerable . 我不知道我将通过哪个具体的集合,除了它的IEnumerable

At run time, I need to find out which type T is (eg System.Double , System.String , etc...). 在运行时,我需要找出T是哪种类型(例如System.DoubleSystem.String等...)。

Is there any way to find it out? 有什么方法可以找到它吗?

UPDATE : I should maybe clarify a bit more the context I am working in (a Linq Provider). 更新 :我应该澄清一下我正在工作的背景(一个Linq提供者)。

My function has a signature like the following, where I get the type of the collection as a parameter: 我的函数有如下的签名,我将集合的类型作为参数:

string GetSymbolForType(Type collectionType)
{

}

Is there any way from collectionType to get the contained objects type? collectionType有没有办法获取包含的对象类型?

From Matt Warren's Blog : 来自Matt Warren的博客

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;
    }
}
myCollection.GetType().GetGenericArguments() 

将返回args类型的数组。

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

will get you the type of the object. 会告诉你对象的类型。

Then you should probably test for your desired types: 然后你应该测试你想要的类型:

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

I use dynamic alot and this is an issue from time to time. 我使用动态很多,这是一个不时出现的问题。

Matt Davis nailed it but you need the index :) 马特戴维斯钉了它但你需要索引:)

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

The type will be what you would expect, it is the type of the object contained in the collection and not any of the generic types surrounding it. 类型将是您所期望的,它是集合中包含的对象的类型,而不是它周围的任何泛型类型。

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

Why not just implement an IEnumerable<T> instead? 为什么不直接实现IEnumerable<T> EG: 例如:

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

Other than that, you'd be better off checking the type of each individual object using is or .GetType rather than trying to work it out from the container itself. 除此之外,您最好使用is.GetType检查每个单独对象的类型,而不是尝试从容器本身处理它。

If that's not an option though and you really need to know the type of the base container you'd basically have to check using is to see what interfaces it implements (EG: IList<int> etc). 如果这不是一个选项,你真的需要知道基本容器的类型,你基本上必须检查使用is看它实现了什么接口(EG: IList<int>等)。 Odds are the type of your array is going to be a generic which means trying to work back from it's name down to it's data type will be quite messy. 赔率是你的数组的类型将是一个泛型,这意味着尝试从它的名称返回到它的数据类型将是非常混乱。

Well I am way way late here but shouldn't this work : 嗯,我在这里很晚,但不应该这样做:

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

   }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM