2009-07-29 4 views
5

Sto cercando di ricavare il tipo di oggetto in fase di esecuzione. Nello specifico ho bisogno di sapere due cose se implementa ICollection o IDto. Attualmente la mia unica soluzione che ho potuto trovare è questo:Come si confrontano i tipi quando si usano i farmaci generici?

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

Tuttavia sono convinto che ci deve essere un modo migliore di questo. Ho provato a confronto in un modo normale, come ad esempio:

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

Tuttavia, questo non funziona quando si utilizza la riflessione ancora quando non si utilizza la riflessione funziona benissimo.

Non voglio scorrere le interfacce per ogni campo della mia entità. Qualcuno potrebbe far luce su un altro metodo in cui farlo? Sì, sto ottimizzando prematuramente, ma sembra troppo brutto, quindi per favore, umorami.

Avvertenze:

  1. potrebbe o potrebbe non essere generico, come IList <> o solo ArrayList quindi il motivo per cui sto cercando ICollection o ICollection <>. Quindi presumo che dovrei usare IsGenericType in un'istruzione if per sapere se testare usando ICollection <> oppure no.

Grazie in anticipo!

risposta

11

questo:

type == typeof(ICollection) 

controllerà se il tipo di proprietà è esattamenteICollection. Cioè, ritornerà vero per:

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

ma non per:

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

Se si desidera controllare se il tipo di proprietà è, o è derivato da, ICollection, il più semplice modo è quello di utilizzare Type.IsAssignableFrom:

typeof(ICollection).IsAssignableFrom(type) 

e lo stesso vale per il generico:

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

In realtà sta attraversando l'intera gerarchia. Inoltre, ICollection <> non implementa direttamente ICollection. – Guvante

+0

Questo ha fatto, ho avuto l'ordine di questi comandi invertiti! Stavo facendo typeof (IList <>). IsAssignableFrom (typeof (ICollection <>). Grazie mille! – joshlrogers

+0

Questo non ha funzionato per me. Ho dovuto postare [un'altra domanda] (http://stackoverflow.com/q/18937119/122781). – HappyNomad

2

L'aiuto type.IsAssignable in questo caso?

EDIT: Scusate, avrebbe dovuto essere Type.IsAssignableFrom

+0

Sfortunatamente no. Quando controllo property.PropertyType.IsAssignableFrom (ICollection <>) e il tipo è un IList <> non riesce ancora. Grazie comunque. – joshlrogers