Как получить тип, содержащийся в коллекции, с помощью отражения - PullRequest
11 голосов
/ 14 декабря 2009

В какой-то части моего кода мне передается коллекция объектов типа T. Я не знаю, какую конкретную коллекцию мне передадут, кроме как это затрудняет IEnumerable.

Во время выполнения мне нужно выяснить, какой тип T (например, System.Double, System.String и т. Д.).

Есть ли способ узнать это?

ОБНОВЛЕНИЕ : Возможно, мне следует немного подробнее уточнить контекст, в котором я работаю (поставщик Linq).

Моя функция имеет подпись, подобную следующей, где я получаю тип коллекции в качестве параметра:

string GetSymbolForType(Type collectionType)
{

}

Есть ли способ из collectionType получить тип содержащихся объектов?

Ответы [ 7 ]

19 голосов
/ 14 декабря 2009

Из Блог Мэтта Уоррена :

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;
    }
}
9 голосов
/ 14 декабря 2009
myCollection.GetType().GetGenericArguments() 

вернет массив типа args.

0 голосов
/ 11 августа 2017

Я использую динамическое много, и это время от времени является проблемой.

Мэтт Дэвис прибил его, но вам нужен индекс:)

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

Тип будет таким, как вы ожидаете, это тип объекта, содержащегося в коллекции, а не какой-либо из общих типов, окружающих его.

0 голосов
/ 30 октября 2016

Ну, я здесь уже поздно, но не стоит ли это работать:

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

   }
0 голосов
/ 14 декабря 2009

Почему бы просто не внедрить IEnumerable<T> вместо этого? EG:

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

Кроме этого, вам лучше проверить тип каждого отдельного объекта, используя is или .GetType, а не пытаться определить его из самого контейнера.

Если это не вариант, и вам действительно нужно знать тип базового контейнера, вам нужно в основном проверить, используя is, чтобы увидеть, какие интерфейсы он реализует (например: IList<int> и т. Д.). Вероятность того, что тип вашего массива будет универсальным, что означает, что попытка вернуться от его имени к типу данных будет довольно грязной.

0 голосов
/ 14 декабря 2009

Не можете просто использовать t.GetType () для этого.

0 голосов
/ 14 декабря 2009
Type t = null
foreach(object o in list)
{
o.GetType();
}

даст вам тип объекта.

Тогда вам, вероятно, следует проверить на нужные вам типы:

if(t == typeof(myClass))
{
dosomething();
}
else if (t == typeof(myOtherClass))
{
dosomethingelse();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...