2016-06-28 3 views
1

J'ai une variable bool comme ceci:Pourquoi puis-je appliquer un opérateur null-conditionnel à une chaîne codée en dur?

bool myBool = true; 

Si j'écris if (myBool == null) je reçois l'avertissement suivant:

Le résultat de l'expression est toujours « faux » depuis une valeur de type « bool 'n'est jamais égal à' null 'de type' bool? '.

C'est clair pour moi car il n'est pas logique de vérifier si une variable non nullable est nulle. Visual Studio remarque cela et marque comme avertissement.

Maintenant, j'ai un string, qui est nullable par défaut, comme je sais.

Pourquoi est-ce que je peux appliquer un opérateur null-conditionnel à un string codé en dur sans Visual Studio s'en apercevoir? Je pense à quelque chose comme ceci:

"This is a string"?.AnyStringMethod(); 

ne devraient pas remarquer Visual Studio que cette string est pas nul du tout?

+6

Votre exemple 'bool' est le compilateur qui vous dit quelque chose sur le type. Votre exemple 'string' nécessiterait que le compilateur vous dise quelque chose sur la valeur. – juharr

+0

@juharr' if (5 == 4) 'est une question de valeurs et n'est pas différente de la question de l'OP où il parle spécifiquement d'une' chaîne' littérale, une valeur sur laquelle le compilateur peut raisonner au moment de la compilation (il le fait déjà interner la valeur pour commencer). – InBetween

+0

@InBetween Je soulignais juste la différence entre les exemples, ne déclarant pas que le compilateur ne peut pas considérer les valeurs lors de la génération des avertissements. – juharr

Répondre

8

Visual Studio doit sortir du du type avec lequel l'opérateur travaille.

Lorsque vous créez un bool, il est impossible qu'il puisse être null par le type, jusqu'à ce que vous modifiez ce type à bool?. Cependant, avec une chaîne codée en dur, même s'il contient du texte dans les guillemets, il n'y a aucune garantie qu'il y restera. La "variable" qui est créée (même comme une simple chaîne) est toujours de type string, qui peut avoir un null et ne pas changer le type.

Ce que vous cherchez serait pour eux d'inspecter la valeur de chaque variable qu'ils créent. S'ils le faisaient, alors pourquoi ne pas vérifier quelque chose comme ça?

var i = 0; 

if (i > 2) // This will always be false! 

Mise à jour

Comme InBetween mentionné dans les commentaires, il y a un peu d'un oubli ici. Avoir une chaîne telle que "Some string" qui n'est pas affectée dans une variable est fonctionnellement équivalente à const string s = "Some string";. Si vous deviez déclarer comme ça, les inspecteurs du code détecteront si vous exécutez une comparaison à ce sujet, comme les suivants:

const string s = "Some String"; 
if (s == null) // This will give a warning that this can't happen 

J'attribuerait cette différence de la manière que le const est géré par rapport à la façon une chaîne statique simple est traitée pourrait être attribuée à différentes équipes de développement travaillant sur différentes parties à des moments différents. Encore une fois, c'est un tel cas qui ne cause pas de gros problèmes qui ne sont pas avertis que personne n'y travaille probablement.

+0

Eh bien, l'argument ici est qu'il s'agit d'une 'chaîne' littérale que le compilateur traite normalement d'une manière différente (' string' interning) à partir de variables normales typées 'string'. Donc, théoriquement, il pourrait émettre un avertissement dans ce cas. La principale raison pour laquelle ce n'est pas que le code est complètement inutile (probablement personne n'y pensait) et plus important encore, inoffensif. – InBetween

+0

La question ne portait pas sur l'entier comme le montre votre code, mais plutôt sur la chaîne et la différence entre le type de valeur et le type de référence. Vous obtenez un plus cependant pour montrer comment faire une variable nullable –

+0

@MikaelPuusaari Vous avez absolument raison. Le code que j'ai montré était un parallèle de ce que le PO demandait. Le texte de ma réponse expliquait ma réponse à leur question. Ce n'est pas parce qu'il se trouve dans un bloc de code que c'est le cœur de la réponse, quand la question n'est pas une question spécifique au code. – krillgar

1

Parce que personne n'y pensait? Votre code est si inutile que personne ne prévoyait qu'il serait jamais utilisé dans le code de production.Je suis à peu près sûr que ce scénario ne s'est même pas produit une fois dans les comités de conception C#, bien que je prenne cela avec un grain de sel jusqu'à ce que quelqu'un comme Eric Lippert jette plus de lumière sur la question.

C# sharp n'est pas né avec toutes les fonctionnalités potentielles, puis quelqu'un décide de l'élaguer. Pour que le compilateur donne un certain avertissement, quelqu'un doit y réfléchir, l'implémenter, le tester et le documenter.

Dans le cas de myBool == null, l'avertissement est justifié car il s'agit d'une erreur plausible qui pourrait potentiellement en faire un code de production et c'est clairement un bug dans la logique du programme. Le deuxième scénario est complètement inoffensif même s'il finit par être mis en production, donc l'avertissement n'a vraiment pas beaucoup de sens.

+0

Normalement, je n'utilise pas de méthodes 'string' comme ça. Mais j'ai écrit une méthode d'extension qui montre un 'MessageDialog' avec le texte défini. Donc, dans mon programme, je peux juste écrire '" Ceci est un message. ". ShowDialog()'. –

0

Parce que bool est d'un type de valeur alors que la chaîne est un type de référence

types de valeur ne peut être nulle, mais les types de référence sont automatiquement nulled par défaut

La raison Indifférent Fume Visual Studio avis, est parce que il est sans importance .. c'est comme demander si le bleu est plus d'une couleur que le vert

0

Un littéral de chaîne est légèrement différent d'un objet chaîne. Je crois que la chaîne littérale est fondamentalement comme une constante, elle est immuable et ne sera jamais nulle.

Lorsque vous affectez un littéral de chaîne à une variable, vous créez une référence à la chaîne dans un emplacement de mémoire. Cette référence peut être nulle. Si vous essayez de concaténer votre variable de chaîne avec une autre chaîne et de la stocker dans votre variable de chaîne d'origine, la chaîne d'origine en mémoire est détruite et une nouvelle chaîne créée est la chaîne concaténée. C'est parce que les chaînes sont toujours immuables.

9

Les avertissements sont pour le code que semble correct mais est réellement faux.

Votre code semble erroné mais fait quand même la bonne chose.

Par conséquent: pas d'avertissement.

+0

Court mais succinct. Belle explication. –