2009-12-06 9 views
8

La meilleure façon d'illustrer ma question est avec ce code exemple:Comment comparer le type d'objet avec un type générique, sans rapport avec l'argument générique?

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 ligne suivante ne fonctionnera pas:

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

est-il un moyen de le faire fonctionner sans changer explicitement Container<> dans Container<int>? Je veux savoir que cet objet est de type 'Container' et que je n'ai vraiment aucun intérêt, est-ce Container<int> ou Container<string>. Des indices autres que des dizaines de lignes de réflexion?

Répondre

23

Essayez:

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

Notez que cela ne retourne true si le type réel est Container<T>. Cela ne fonctionne pas pour les types dérivés. Par exemple, il va revenir false pour ce qui suit:

class StringContainer : Container<string> 

Si vous avez besoin pour le faire fonctionner dans ce cas, vous devez traverser la hiérarchie d'héritage et tester chaque classe de base pour être 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); 
} 
Questions connexes