2009-07-29 9 views
5

Ich versuche den Typ eines Objekts zur Laufzeit abzuleiten. Insbesondere muss ich zwei Dinge wissen, ob es ICollection oder IDto implementiert. Zur Zeit meine einzige Lösung, die ich die Lage gewesen zu finden, ist dies:Wie vergleiche ich Typen bei der Verwendung von Generika?

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; 
    } 

Allerdings bin ich überzeugt, dass es ein besserer Weg, als dies sein muss. Ich habe versucht, in einer normalen Weise zu vergleichen, wie:

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

Dies ist jedoch nicht, wenn noch mit Reflexion, wenn sie nicht mithilfe von Reflektion es funktioniert gut.

Ich möchte nicht die Schnittstellen für jedes Feld meiner Entität durchlaufen. Könnte jemand eine andere Methode beleuchten, um dies zu tun? Ja, ich optimiere vorzeitig, aber es sieht auch hässlich aus.

Caveats:

  1. Es könnte oder nicht generisch sein könnte, wie IList <> oder Arraylist nur so, warum ich für ICollection oder ICollection <> suchen. Also nehme ich an, ich sollte IsGenericType in einer if-Anweisung verwenden, um zu wissen, ob mit ICollection <> oder nicht zu testen ist.

Vielen Dank im Voraus!

Antwort

11

Dieses:

type == typeof(ICollection) 

wird überprüfen, ob die Art der Immobilie ist genauICollection. Das heißt, es wird return true für:

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

aber nicht für:

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

Wenn Sie, wenn die Art der Immobilie überprüfen möchten ist, oder ist abgeleitet von, ICollection, die einfachste Art und Weise verwenden Type.IsAssignableFrom:

typeof(ICollection).IsAssignableFrom(type) 

und das gleiche gilt für generic:

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

Tatsächlich durchläuft er die gesamte Hierarchie. Außerdem implementiert ICollection <> ICollection nicht direkt. – Guvante

+0

Das war es, ich hatte die Reihenfolge dieser Befehle umgekehrt! Ich habe typeof (IList <>). IsAssignableFrom (typeof (ICollection <>). Vielen Dank! – joshlrogers

+0

Dies hat nicht funktioniert für mich. Ich musste [eine andere Frage] (http://stackoverflow.com/q/18937119/122781). – HappyNomad

2

Hilft type.IsAssignable in diesem Fall?

EDIT: Sorry, sollte es gewesen sein Type.IsAssignableFrom

+0

Leider nicht. Wenn ich property.PropertyType.IsAssignableFrom (ICollection <>) überprüfe und der Typ eine IList <> ist, schlägt es immer noch fehl. Trotzdem danke. – joshlrogers

Verwandte Themen