Определите, имеет ли поле универсальный тип или нет - PullRequest
1 голос
/ 13 августа 2011

Можно ли с помощью отражения определить, является ли поле универсальным типом или нет?

Если это возможно, как это можно сделать?

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

EDIT:

Если a имеет тип, определенный как в следующем примере, и НЕ ИМЕЕТ экземпляр типа Holder<T>, но только экземпляр System.Type извлекается через System.Reflection.Assembly.GetTypes и экземпляр System.Reflection.FieldInfo, описывающий поле _instance , как я могу определить, имеет ли поле _instance универсальный тип

public class Holder<T>
{
   private T _instance;
}

Ответы [ 3 ]

6 голосов
/ 13 августа 2011

Используя FieldInfo для поля, вы можете проверить свойство IsGenericType свойства FieldType, если хотите узнать, является ли поле универсальным типом само по себе.

 var info = type.GetField("myField",BindingFlags.Private);
 if (info != null)
 {
      if (info.FieldType.IsGenericType)
      {
           Console.WriteLine( "The type of the field is generic" );
      }
 }

Если вам нужно проверить, еслиполе относится к типу универсального в определении универсального класса, тогда вместо этого вы захотите проверить IsGenericParameter.

 var info = type.GetField("myField",BindingFlags.Private);
 if (info != null)
 {
      if (info.FieldType.IsGenericParameter)
      {
           Console.WriteLine( "The type of the field is the generic parameter of the class" );
      }
 }

Вы, конечно, можете объединить их.Проверка, является ли поле универсальным типом в определенном в общем классе, является более проблематичным, но все же может быть выполнено.Вы просто должны проверить параметры типа универсального типа, чтобы увидеть, есть ли у одного из них установлен IsGenericParameter.Обратите внимание, что следующий пример имеет глубину только один уровень;если вы хотите что-то всеобъемлющее, вам нужно определить метод и использовать его рекурсивно.

var info = type.GetField("myField",BindingFlags.Private);
if (info != null)
{
     if (info.FieldType.IsGenericType)
     {
         foreach (var subType in info.FieldType.GetGenericArguments())
         {
             if (subType.IsGenericParameter)
             {
                 Console.WriteLine( "The type of the field is generic" );
             }
         }
     }
}
2 голосов
/ 13 августа 2011

Попробуйте

field.GetType().IsGenericType

Свойство Type.IsGenericType :

Получает значение, указывающее, является ли текущий тип универсальным типом.

1 голос
/ 13 августа 2011

Позвольте мне перефразировать ваш вопрос так, как я его понимаю:

У меня есть универсальный тип, и я хочу выяснить, содержит ли определенный тип поля (один из) аргумент типа.Как мне это сделать?

Если вы хотите узнать, является ли определенный тип универсальным параметром, вы можете использовать свойство IsGenericParameter .Это возвращает true для T, но не для List<T>.Если вы хотите этого, используйте рекурсию:

bool ContainsGenericParameter(Type fieldType)
{
    return fieldType.IsGenericParameter ||
        fieldType.GetGenericArguments().Any(t => ContainsGenericParameter(t));
}

Например, если у вас есть такой тип:

public class Holder<T>
{
   private T _t;
   private int _int;
   private List<T> _listT;
   private List<int> _listInt;
}

Этот запрос

typeof(Holder<>)
    .GetFields(BindingFlags.NonPublic | BindingFlags.Instance)
    .Select(f => new { f.Name, Generic = ContainsGenericParameter(f.FieldType) })

Вернет что-то вроде этого:

Name     Generic
_t       True
_int     False
_listT   True
_listInt False
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...