2010-11-05 9 views
3

Dire que j'ai une simple classe générique comme suitComment puis-je tester si une instance d'une classe est un type générique spécifique?

public class MyGenericClass<t> 
{ 
    public T {get;set;} 
} 

Comment puis-je tester si une instance d'une classe est-ce un MyGenericClass? Par exemple, je veux faire quelque chose comme ceci:

MyGenericClass x = new MyGenericClass<string>(); 
bool a = x is MyGenericClass; 
bool b = x.GetType() == typeof(MyGenericClass); 

Pourtant, je ne peux pas faire référence à MyGenericClass. Visual Studio veut toujours que j'écrive MyGenericClass<something>.

Répondre

2

Pour tester si votre instance est de type MyGenericClass<T>, vous pouvez écrire quelque chose comme ceci.

MyGenericClass<string> myClass = new MyGenericClass<string>(); 
bool b = myClass.GetType().GetGenericTypeDefinition() == typeof(MyGenericClass<>); 

Si vous voulez être en mesure de déclarer votre objet comme MyGenericClass au lieu de MyGenericClass<string>, il aurait besoin d'une base non générique de MyGenericClass pour faire partie de l'arbre d'héritage. Mais à ce stade, vous ne pourrez vous référer aux propriétés/méthodes de la base que si vous les convertissez plus tard en un type générique dérivé. Vous ne pouvez pas omettre le paramètre de type en déclarant directement une instance générique *

* Vous pouvez, bien sûr, choisir d'utiliser l'inférence de type et d'écrire

var myClass = new MyGenericClass<string>(); 

Edit:. Adam Robinson fait un bon point les commentaires, disons que vous avez class Foo : MyGenericClass<string>. Le code de test ci-dessus n'identifie pas une instance de Foo comme MyGenericClass<>, mais vous pouvez toujours écrire du code pour le tester.

Func<object, bool> isMyGenericClassInstance = obj => 
    { 
     if (obj == null) 
      return false; // otherwise will get NullReferenceException 

     Type t = obj.GetType().BaseType; 
     if (t != null) 
     { 
      if (t.IsGenericType) 
       return t.GetGenericTypeDefinition() == typeof(MyGenericClass<>); 
     } 

     return false; 
    }; 

bool willBeTrue = isMyGenericClassInstance(new Foo()); 
bool willBeFalse = isMyGenericClassInstance("foo"); 
+0

Notez que cela ne fonctionnera pas si la classe est * dérivée * d'une forme générique de la classe. En d'autres termes, 'public class Foo: MyGenericClass {}' ne serait pas admissible. –

+0

@Adam, bon point. Vous pouvez écrire du code pour aller un peu plus loin pour tester. Je vais ajouter * une idée * sur la façon de le faire. –

0
List<int> testInt = new List<int>(); 
List<string> testString = new List<string>(); 

if (testInt .GetType().Equals(testString.GetType())) 
Console.WriteLine("Y"); 
else Console.WriteLine("N"); 

son 'N'

et

testInt.GetType().Equals(typeof(List<int>)) 
is true 

mais si tu veux juste nom de classe

testInt.GetType().FullName 
0

Vous pouvez, si vous le souhaitez, faire la classe générique implémenter une interface arbitraire (éventuellement vide). Tester si un objet appartenait à la classe générique générale serait alors simplement une question de test pour savoir s'il a implémenté cette interface. Pas besoin d'utiliser explicitement la réflexion.