web-dev-qa-db-fra.com

Où et quand utiliser GetType () ou typeof ()?

Pourquoi ça marche

if (mycontrol.GetType() == typeof(TextBox))
{} 

et cela non?

Type tp = typeof(mycontrol);

Mais ça marche

Type tp = mycontrol.GetType();

J'utilise moi-même l'opérateur is pour vérifier le type, mais ma compréhension échoue lorsque j'utilise typeof() et GetType()

Où et quand utiliser GetType() ou typeof()?

55
Nikhil Agrawal

typeof est un opérateur qui obtient un type connu à au moment de la compilation (ou au moins un type générique paramètre). L'opérande de typeof est toujours le nom d'un type ou d'un paramètre de type - jamais une expression avec une valeur (par exemple, une variable). Voir le spécification du langage C # pour plus de détails.

GetType() est une méthode que vous appelez sur des objets individuels pour obtenir le type d'exécution du objet.

Notez que si vous seulement voulez exactement des instances de TextBox (plutôt que des instances de sous-classes), vous utiliseriez habituellement:

if (myControl is TextBox)
{
    // Whatever
}

Ou

TextBox tb = myControl as TextBox;
if (tb != null)
{
    // Use tb
}
95
Jon Skeet

typeof est appliqué à un nom de type ou à un paramètre de type générique connu au moment de la compilation. GetType est appelé sur un objet au moment de l'exécution. Dans les deux cas, le résultat est un objet du type System.Type contenant des méta-informations sur un type.

Si tu as

string s = "hello";

Ces deux lignes sont valables

Type t1 = typeof(string);
Type t2 = s.GetType();

t1 == t2 ==> true

Mais

object obj = "hello";

Ces deux lignes sont valables

Type t1 = typeof(object); // ==> object
Type t2 = obj.GetType();  // ==> string!

t1 == t2 ==> false

c'est-à-dire que le type de temps de compilation (type statique) de la variable obj n'est pas identique au type d'exécution de l'objet référencé par obj.


Types de test

Si, toutefois, vous voulez seulement savoir si mycontrol est un TextBox, alors vous pouvez simplement tester

if (mycontrol is TextBox)

Notez que cela n’est pas complètement équivalent à

if (mycontrol.GetType() == typeof(TextBox))    

parce que mycontrol pourrait avoir un type dérivé de TextBox. Dans ce cas, la première comparaison donne true et la seconde false! La première et la variante la plus facile est OK dans la plupart des cas, puisqu'un contrôle dérivé de TextBox hérite de tout ce que TextBox a, ajoute probablement plus et est donc compatible avec les assignations à TextBox .

public class MySpecializedTextBox : TextBox
{
}

MySpecializedTextBox specialized = new MySpecializedTextBox();
if (specialized is TextBox)       ==> true

if (specialized.GetType() == typeof(TextBox))        ==> false

Casting

Si vous avez le test suivant suivi d'un cast et que T est nullable ...

if (obj is T) {
    T x = (T)obj; // The casting tests, whether obj is T again!
    ...
}

... vous pouvez le changer en ...

T x = obj as T;
if (x != null) {
    ...
}

Tester si une valeur est d'un type donné et le transtypage (qui implique à nouveau le même test) peut prendre beaucoup de temps pour de longues chaînes d'héritage. L'utilisation de l'opérateur as suivie d'un test pour null est plus performante.

À partir de C # 7.0, vous pouvez simplifier le code en utilisant la correspondance de modèle:

if (obj is T t) {
    // t is a variable of type T having a non-null value.
    ...
}
43

typeOf est un mot clé C # utilisé lorsque vous avez le nom de la classe. Il est calculé lors de la compilation et ne peut donc pas être utilisé sur une instance créée à l'exécution. GetType est une méthode de la classe d'objet pouvant être utilisée sur une instance.

8
Fr33dan

Vous trouverez peut-être plus facile d'utiliser le mot-clé is :

if (mycontrol is TextBox)
5
Jonathon Reinhart