2009-07-29 8 views
5

J'essaie de dériver le type d'un objet à l'exécution. Plus précisément, j'ai besoin de savoir deux choses si elle implémente ICollection ou IDto. À l'heure actuelle ma seule solution que j'ai pu trouver est la suivante:Comment comparer les types lors de l'utilisation de génériques?

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

Cependant, je suis convaincu qu'il doit y avoir une meilleure façon que cela. Je l'ai essayé à comparer de façon normale, comme:

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

Cependant, cela ne fonctionne pas lors de l'utilisation réflexion encore lorsqu'ils ne sont pas en utilisant la réflexion, il fonctionne très bien. Je ne veux pas parcourir les interfaces pour chaque champ de mon entité. Quelqu'un pourrait-il faire la lumière sur une autre méthode pour faire cela? Oui, j'optimise prématurément, mais ça a l'air moche aussi, s'il te plait humour moi.

Avertissements:

  1. Il pourrait ou ne pourrait pas être générique, comme IList <> ou tout simplement ArrayList donc pourquoi je cherche ICollection ou ICollection <>. Donc je suppose que je devrais utiliser IsGenericType dans une instruction if pour savoir s'il faut tester en utilisant ICollection <> ou non.

Merci d'avance!

Répondre

11

Ce:

type == typeof(ICollection) 

vérifiera si le type de propriété est exactementICollection. Autrement dit, il retourne vrai pour:

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

mais pas pour:

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

Si vous voulez vérifier si le type de propriété est, ou est dérivé de, ICollection, le plus simple est d'utiliser Type.IsAssignableFrom:

typeof(ICollection).IsAssignableFrom(type) 

et va de même pour les médicaments génériques:

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

En fait, il traverse toute la hiérarchie. De plus, ICollection <> n'implémente pas ICollection directement. – Guvante

+0

Cela fait, j'ai eu l'ordre de ces commandes inversées! Je faisais typeof (IList <>). IsAssignableFrom (typeof (ICollection <>) Merci beaucoup – joshlrogers

+0

Cela n'a pas fonctionné pour moi, j'ai dû poster [une autre question] (http://stackoverflow.com/q/18937119/122781). – HappyNomad

2

Est-ce que type.IsAssignable aide dans ce cas?

EDIT: Désolé, il aurait dû être Type.IsAssignableFrom

+0

Malheureusement non. Lorsque je vérifie property.PropertyType.IsAssignableFrom (ICollection <>) et que le type est un IList <>, il échoue toujours. Merci quand même. – joshlrogers

Questions connexes