2009-12-06 29 views
8

modo migliore per illustrare la mia domanda è con questo codice di esempio:Come confrontare il tipo di oggetto con un tipo generico, irrilevante per argomento generico?

class Item {} 
    class Container<T> {} 
    class Program 
    { 
    static void DoSomething(object something) 
    { 
     if(typeof(Item) == something.GetType()) 
     { 
     System.Console.WriteLine("Item"); 
     } 
     else if(typeof(Container<>) == something.GetType()) 
     { 
     System.Console.WriteLine("Container<>"); 
     } 
    } 

    static void Main(string[] args) 
    { 
     DoSomething(new Item()); 
     DoSomething(new Container<int>()); 
    } 
    } 

La riga seguente non funziona:

else if(typeof(Container<>) == something.GetType()) 

E 'un modo per farlo funzionare senza cambiare esplicitamente Container<> in Container<int>? Voglio sapere che l'oggetto è di tipo "Container" e non ho alcun interesse è lo Container<int> o Container<string>. Qualche suggerimento oltre a dozzine di linee di riflessione?

risposta

23

Prova:

typeof(Container<>) == something.GetType().GetGenericTypeDefinition() 

Si noti che questo sarà solo tornare vero se il tipo effettivo è Container<T>. Non funziona per i tipi derivati. Per esempio, si tornerà false per i seguenti:

class StringContainer : Container<string> 

Se è necessario per farlo funzionare per questo caso, si deve attraversare la gerarchia di ereditarietà e testare ogni classe di base per essere Container<T>:

static bool IsGenericTypeOf(Type genericType, Type someType) 
{ 
    if (someType.IsGenericType 
      && genericType == someType.GetGenericTypeDefinition()) return true; 

    return someType.BaseType != null 
      && IsGenericTypeOf(genericType, someType.BaseType); 
} 
Problemi correlati