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()
?
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
}
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.
...
}
Vous trouverez peut-être plus facile d'utiliser le mot-clé is
:
if (mycontrol is TextBox)