2010-12-02 2 views
7

Il fait juste sens parfois pour vérifier si un objet n'est pas le type de X, de sorte que vous devez faire ceci:Pourquoi n'y a-t-il pas un mot clé "n'est pas" dans C#?

if(this.GetType() != typeof(X)) 
{ 
     //Do my thing. 

} 

Ce qui est un peu lourd à mon avis, ne serait pas quelque chose comme ça plus agréable:

if(this is not X) 
{ 
    //Do my thing 
} 
+0

Ceux-ci ne seraient pas fonctionnellement équivalents si 'X' était un sous-type de' this.GetType() '. –

Répondre

20

Qu'en est-il logique opérateur NOT !, correspond à la description du mot 'non' très bien:

if (!(this is X)) 
{ 
    //Do my thing 
} 

Comme d'autres ont souligné cependant, is est également utilisé pour vérifier si la classe d'un objet hérite d'une classe ou implémente une interface, ce qui est plutôt différent de GetType().

Les deux CodeInChaos et StriplingWarrior ont des explications raisonnables pour expliquer pourquoi il n'y a pas de mot-clé not en C#.

+1

Nous n'aurions pas besoin de faire un mot-clé 'not'. Il suffirait probablement de faire un mot-clé similaire à 'yield return'. Peut-être un peu déroutant puisque la plupart des programmeurs C# ne sont pas habitués à deux mots-clés (ou devrais-je les appeler des phrases-clés?). Donc, il faudrait utiliser 'isnot' qui IMO semble laid. – CodesInChaos

+1

J'aimerais voir "!" permis dans quelques cas particuliers en C où il aurait une signification claire, mais pas actuellement légal. Un cas serait en dehors des parenthèses pour un si, while, etc.(dans de tels contextes, il devrait inverser strictement la condition, indépendamment des surcharges de l'opérateur). Un autre cas de ce genre pourrait être bien ici: autoriser "this! Is x", afin d'éviter des parenthèses supplémentaires. – supercat

4

Utiliser un bon symbole « bang ol:

if (!(pero is Human)) 
{ 

} 

BTW, is est différent, car il attire non seulement la classe dérivée de feuilles, mais toute la hiérarchie de celui-ci, les deux interfaces et classes.

Ainsi, pour

class Human: ICanSpeak, Mamal 
{ 
... 
} 

Human h; 

if (h is Human) { will be true } 
if (h is ICanSpeak) { will be true } 
if (h is Mamal) { will also be true } 
5

Notez que this.GetType()! = typeof(X) renvoie false si cela est dérivé (ou instruments en cas d'un type d'interface), mais pas identique à X, alors que this is X renvoie true.

Et pourquoi y aurait-il un mot-clé distinct lorsque vous pouvez simplement utiliser !(a is X)? Cela gonfle la langue avec peu de gain. Comme Eric Lippert aime souligner que chaque nouvelle fonctionnalité linguistique doit offrir suffisamment d'avantages pour compenser le codage, la documentation, les tests et bien sûr la complexité accrue de la langue. Et un opérateur not is n'offre tout simplement pas assez.

Vous pouvez mettre en œuvre une méthode d'extension, mais je pense que c'est stupide:

public static bool IsNot<T>(this object obj) 
{ 
    return !(obj is T); 
} 
+4

Mis à part le fait que les méthodes d'extension sur un objet sont une pratique de programmation douteuse, ce n'est pas une mauvaise méthode d'extension. Je ne dis pas que je l'utiliserais, mais je pense que c'est assez raisonnable. –

+0

@Eric: Je souhaitais vraiment que C# ait aussi un opérateur non "non" en plus de! On pourrait dire que c'est inutile mais! est vraiment difficile à voir/repérer dans le code où "sinon (vector.IsNormalized)" est beaucoup plus facile à analyser visuellement que "if! (vector.IsNormalized)", mais je suppose que C# l'a fait pour ne pas aliéner les gens C++ , droite? –

+2

@Eric, puis-je demander pourquoi les méthodes d'extensions d'objets sont considérées comme une mauvaise pratique? – dexter

9

Ajout d'un mot-clé à une langue ajoute de la complexité. L'ajout d'un mot-clé à une langue après la spécification initiale peut entraîner des modifications de rupture pour les personnes effectuant une mise à niveau. Donc, les mots-clés ne sont généralement ajoutés que s'il y a un argument très fort en leur faveur. Dans ce cas, les autres réponses soulignent, il est très facile d'utiliser l'opérateur bang:

if (!(pero is Human)) ... 

... qui un développeur typique C# (/ C/C++/Java) lirait « sinon (pero est humain) ". Donc, il n'y a pas beaucoup de justification pour un mot-clé spécial.

+1

Par exemple, nous n'avons pas de mot-clé 'yield' en C# car cela aurait été un changement de rupture. D'un autre côté, le rendement return x était une syntaxe illégale et donc pas de changement de rupture. – CodesInChaos

+1

@CodeInChaos: Oui, mais un mot clé 'is not' pourrait techniquement tomber dans la même catégorie que' yield return'. La différence est qu'il faut beaucoup de travail pour émuler le «yield return», alors que l'opérateur bang et les parenthèses suffisent à émuler 'is not'. – StriplingWarrior

+0

Je crois qu'un opérateur 'isnot' (pas d'espaces) serait très facile et sûr à implémenter. Je voterais certainement pour qu'il fasse partie de la syntaxe C#. Tant de fois en codant vite je l'ai presque écrit. Cela vient très naturellement. Il aurait aussi intellisense et il permettrait d'économiser tout le typage de l'opérateur de support et de négation. En bref, cela aurait été utile. – GDS

Questions connexes