2009-07-29 13 views
5

Próbuję uzyskać typ obiektu w czasie wykonywania. W szczególności muszę znać dwie rzeczy, czy implementuje ICollection czy IDto. Obecnie moje jedyne rozwiązanie, które udało mi się znaleźć, to:Jak porównać typy przy użyciu generycznych?

private static bool IsACollection(PropertyDescriptor descriptor) 
    { 
     bool isCollection = false; 

     foreach (Type type in descriptor.PropertyType.GetInterfaces()) 
     { 
      if (type.IsGenericType) 
      { 
       if (type.GetGenericTypeDefinition() == typeof(ICollection<>)) 
       { 
        isCollection = true; 
        break; 
       } 
      } 
      else 
      { 
       if (type == typeof(ICollection)) 
       { 
        isCollection = true; 
        break; 
       } 
      } 
     } 


     return isCollection; 
    } 

    private static bool IsADto(PropertyDescriptor descriptor) 
    { 
     bool isDto = false; 

     foreach (Type type in descriptor.PropertyType.GetInterfaces()) 
     { 
      if (type == typeof(IDto)) 
      { 
       isDto = true; 
       break; 
      } 
     }   
     return isDto; 
    } 

Jestem jednak przekonany, że musi istnieć lepsza droga niż to. Próbowałem porównując w normalny sposób, takich jak:

if(descriptor.PropertyType == typeof(ICollection<>)) 

Jednak to się nie powiedzie, gdy przy użyciu odbicia jeszcze gdy nie przy użyciu odbicia działa dobrze.

Nie chcę iterować przez interfejsy dla każdego pola mojej jednostki. Czy ktoś mógłby rzucić trochę światła na inną metodę, aby to zrobić? Tak, przedwcześnie optymalizuję, ale wygląda to też brzydko, więc proszę mnie posmakować.

Ostrzeżenia:

  1. To może lub nie może być ogólne, takie jak IList <> lub po prostu ArrayList więc dlaczego szukam kolekcji ICollection lub kolekcji ICollection <>. Zakładam więc, że powinienem używać IsGenericType w instrukcji if, aby wiedzieć, czy testować przy użyciu ICollection <> czy też nie.

Z góry dziękuję!

Odpowiedz

11

to:

type == typeof(ICollection) 

sprawdzi, czy rodzaj nieruchomości jest dokładnieICollection. Oznacza to, że powróci prawdziwe dla:

public ICollection<int> x { get; set; } 

ale nie dla:

public List<int> x { get; set; } 

Jeśli chcesz sprawdzić, czy rodzaj nieruchomości jest albo pochodzi od, ICollection, najprostsza sposobem jest użycie Type.IsAssignableFrom:

typeof(ICollection).IsAssignableFrom(type) 

i to samo dotyczy ogólna:

typeof(ICollection<>).IsAssignableFrom(type.GetGenericTypeDefinition()) 
+0

W rzeczywistości przechodzi przez całą hierarchię. Dodatkowo ICollection <> nie implementuje bezpośrednio ICollection. – Guvante

+0

Zrobiłem to, zmieniłem kolejność poleceń! Robiłem typeof (IList <>). IsAssignableFrom (typeof (ICollection <>) .Dziękuję bardzo! – joshlrogers

+0

To nie działa dla mnie.Miałem wysłać [inne pytanie] (http://stackoverflow.com/q/18937119/122781). – HappyNomad

2

Czy pomoc w tej sprawie jest type.IsAssignable?

EDIT: Niestety, to powinna być Type.IsAssignableFrom

+0

Niestety nie. Kiedy sprawdzam właściwość.PropertyType.IsAssignableFrom (ICollection <>), a typ jest IList <>, nadal nie działa. Ale dziękuję. – joshlrogers

Powiązane problemy