2010-05-14 2 views
9

У меня есть функция с этим кодом:Игнорировать свойство коллекции в PropertyInfo

foreach (PropertyInfo propertyInfo in typeof(T).GetProperties()){ 
//SOME CODE 
if (propertyInfo.CanWrite) 
    propertyInfo.SetValue(myCopy, propertyInfo.GetValue(obj, null), null); 
} 

Я хотел бы избежать, чтобы проверить «коллекцию» свойство; для этого сейчас я вставляю этот элемент управления:

if (propertyInfo.PropertyType.Name.Contains("List") 
    || propertyInfo.PropertyType.Name.Contains("Enumerable") 
    || propertyInfo.PropertyType.Name.Contains("Collection")) 
    continue; 

но, это не нравится мне!

Это лучший способ сделать это?

ответ

14

Я думал, вы можете проверить интерфейсы типа орудий собственности. (Удалены лишние интерфейсы, а IList наследует ICollection и ICollection наследует IEnumerable.)

static void DoSomething<T>() 
{ 
    List<Type> collections = new List<Type>() { typeof(IEnumerable<>), typeof(IEnumerable) }; 

    foreach (PropertyInfo propertyInfo in typeof(T).GetProperties()) 
    { 
     if (propertyInfo.PropertyType != typeof(string) && propertyInfo.PropertyType.GetInterfaces().Any(i => collections.Any(c => i == c))) 
     { 
      continue; 
     } 

     Console.WriteLine(propertyInfo.Name); 
    } 
} 

Я добавил код, чтобы не отвергнуть строку, поскольку она реализует IEnumerable, а также, и я понял, что вы можете держать окружающих.

В свете избыточности предварительного списка интерфейсов сбора, может быть проще просто написать такой код

static void DoSomething<T>() 
{ 
    foreach (PropertyInfo propertyInfo in typeof(T).GetProperties()) 
    { 
     if (propertyInfo.PropertyType != typeof(string) 
      && propertyInfo.PropertyType.GetInterface(typeof(IEnumerable).Name) != null 
      && propertyInfo.PropertyType.GetInterface(typeof(IEnumerable<>).Name) != null) 
     { 
      continue; 
     } 

     Console.WriteLine(propertyInfo.Name); 
    } 
} 
+0

+1 Убрали мой ответ, поскольку это лучше. – GenericTypeTea

+7

IEnumerable <> реализует IEnumerable, нет необходимости проверять IEnumerable <> – MaLio

8

Возможно, я проверял: IEnumerable.

if ((typeof(string) != propertyInfo.PropertyType) 
    && typeof(IEnumerable).IsAssignableFrom(propertyInfo.PropertyType)) 
{ 
    continue; 
} 
+0

О, о, теперь у меня есть проблема ... это условие истинно также для свойства string. Возможно? –

+0

Я решаю с другим опубликованным решением. –

+0

@ LukePet: Строки реализуют 'IEnumerable', потому что это коллекции символов. Ответ Энтони конкретно исключает строки, поэтому вы правы, чтобы выбрать один (и я обновил свой ответ, чтобы последовать его примеру). – LukeH

4
bool isCollection = typeof(System.Collections.IEnumerable) 
          .IsAssignableFrom(propertyInfo.PropertyType); 
+0

лучше, чем правильный ответ – JeffZhnn