J'utilise le type "bool" pour les variables comme j'étais habitué en C++, et j'essaie de mettre les valeurs des fonctions ou des propriétés que je m'attends à être booléennes dans ma variable. Cependant, je rencontre souvent des cas où le type de résultat est "bool?" et non "bool" et le casting implicite échoue.
Quelle est la différence entre les deux et quand chacun est-il utilisé? De plus, dois-je utiliser "bool?" comme type pour ma variable? Est-ce la meilleure pratique?
Le ?
le symbole après un type n'est qu'un raccourci vers type Nullable , bool?
est équivalent à Nullable<bool>
.
bool
est un type de valeur , cela signifie qu'il ne peut pas être null
, donc le type Nullable vous permet essentiellement d'envelopper les types de valeur et de pouvoir affecter null
pour eux.
bool?
peut contenir trois valeurs différentes: true
, false
et null
.
De plus, aucun opérateur de court-circuit (&& ||) n'est défini pour bool?
Seuls les opérateurs logiques ET, OU inclusifs, sont définis et se comportent comme suit:
x y x & y x | y
true true true true
true false false true
true null null true
false true false true
false false false false
false null false null
null true null true
null false false null
null null null null
Le type Nullable est fondamentalement une structure générique, qui a les propriétés publiques suivantes:
public struct Nullable<T> where T: struct
{
public bool HasValue { get; }
public T Value { get; }
}
La propriété HasValue
indique si l'objet actuel a une valeur, et la propriété Value
obtiendra la valeur actuelle de l'objet, ou si HasValue a la valeur false, elle lèvera une InvalidOperationException.
Maintenant, vous devez vous demander quelque chose, Nullable est une structure, un type de valeur qui ne peut pas être nul, alors pourquoi l'instruction suivante est-elle valide?
int? a = null;
Cet exemple se compilera en ceci:
.locals init (valuetype [mscorlib]System.Nullable`1<int32> V_0)
IL_0000: ldloca.s V_0
IL_0002: initobj valuetype [mscorlib]System.Nullable`1<int32>
Un appel à initobj , qui initialise chaque champ du type valeur à une adresse spécifiée à une référence nulle ou un 0 du type primitif approprié.
Voilà, ce qui se passe ici est la valeur par défaut initialisation de la structure .
int? a = null;
Est équivalent à:
Nullable<int> a = new Nullable<int>();
bool?
est nullable tandis que bool
ne l'est pas.
bool? first;
bool second;
Dans le code ci-dessus, first
sera null
tandis que second
sera false
.
Une utilisation typique consiste à savoir si une affectation a été effectuée pour la variable. Puisque bool
est un type de valeur (tout comme int
, long
, double
, DateTime
et certains autres autres types), il sera toujours initialisé à une valeur par défaut (false
dans le cas d'un bool
, 0
dans le cas d'un int
). Cela signifie que vous ne pouvez pas facilement savoir si c'est false
parce qu'un code lui a été attribué false
, ou s'il est false
parce qu'il n'a pas encore été attribué. Dans ce cas bool?
est très pratique.
Chaque fois que vous voyez le? caractère suivant un nom de type, c'est un raccourci pour Nullable<TypeName>
. Nullable est un type spécial qui permet aux types de valeur d'agir comme une valeur nulle. C'est une façon d'exprimer explicitement un type de valeur qui peut avoir une valeur sans valeur.
Pour bool, il transforme efficacement la variable en une valeur à trois états
Ajouter ?
rend le type nul. Ce qui signifie que vous pouvez le faire:
bool? x = null;
Et ce serait totalement OK.
bool? signifie que le booléen est nul et est du sucre syntaxique pour une structure Nullable<bool>
. Étant donné qu'un booléen est un type de valeur, vous ne pouvez pas le définir sur null, mais il existe certains cas où vous souhaitez aimer dans une classe d'accès aux données car les champs de base de données peuvent avoir des valeurs nulles.
bool
ne peut contenir que des valeurs true
et false
tandis que bool?
peut également avoir une valeur null
.
Un autre bon endroit pour utiliser bool? est dans une méthode pour ajouter une vérification nulle
public bool? IsTurkeyStillInFridge(Turkey turkey)
{
if (turkey == null)
return null;
else if (fridge.Contains(turkey))
return true;
else
return false;
}
bool? canStayAtDesk = IsTurkeyStillInFridge(turkey);
if (canStayAtDesk == null)
MessageBox.Show("No turkey this year, check for ham.");
else if (canStayAtDesk == true)
MessageBox.Show("Turkey for lunch. Stay at desk.");
else
MessageBox.Show("Turkey's gone, go out to lunch.");
bool signifie que vous pouvez avoir des valeurs vraies et fausses. bool? signifie que vous pouvez avoir une valeur vraie, fausse et nulle.
Cela fonctionne pour datetime et booléens.