A traversé cette ligne de code:
FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();
Que signifient les deux points d’interrogation, s’agit-il d’une sorte d’opérateur ternaire? Il est difficile de chercher dans Google.
C'est l'opérateur de coalescence nul et tout à fait comme l'opérateur ternaire (immédiat-si). Voir également ?? Opérateur - MSDN .
FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();
s'étend à:
FormsAuth = formsAuth != null ? formsAuth : new FormsAuthenticationWrapper();
qui s'étend ensuite à:
if(formsAuth != null)
FormsAuth = formsAuth;
else
FormsAuth = new FormsAuthenticationWrapper();
En anglais, cela signifie "Si tout ce qui est à gauche n'est pas nul, utilisez-le, sinon utilisez ce qui est à droite."
Notez que vous pouvez utiliser n'importe quel nombre de ceux-ci en séquence. L'instruction suivante assignera le premier Answer#
non nul à Answer
(si toutes les réponses sont nulles, la Answer
est nulle):
string Answer = Answer1 ?? Answer2 ?? Answer3 ?? Answer4;
En outre, même si l’expansion ci-dessus est conceptuellement équivalente, le résultat de chaque expression n’est évalué qu’une fois. Ceci est important si, par exemple, une expression est un appel de méthode avec des effets secondaires. (Nous remercions @ Joey pour l'avoir signalé.)
Tout simplement parce que personne n’a encore prononcé les mots magiques: c’est l’opérateur de fusion null. Il est défini dans la section 7.12 de la spécification du langage C # 3.0 .
C'est très pratique, notamment à cause de la façon dont cela fonctionne lorsqu'il est utilisé plusieurs fois dans une expression. Une expression de la forme:
a ?? b ?? c ?? d
donnera le résultat de l'expression a
s'il est non nul, sinon essayez b
, sinon essayez c
, sinon essayez d
. Il court-circuite à chaque point.
De même, si le type de d
est non nullable, le type de l'expression entière n'est pas non plus nullable.
C'est l'opérateur de coalescence nul.
http://msdn.Microsoft.com/en-us/library/ms173224.aspx
Oui, presque impossible à rechercher à moins de savoir comment ça s'appelle! :-)
EDIT: Et c'est une fonctionnalité intéressante d'une autre question. Vous pouvez les enchaîner.
Merci à tous, voici l'explication la plus succincte que j'ai trouvée sur le site MSDN:
// y = x, unless x is null, in which case y = -1.
int y = x ?? -1;
??
est là pour fournir une valeur pour un type nullable lorsque la valeur est null. Ainsi, si formsAuth est null, il renverra un nouveau FormsAuthenticationWrapper ().
Les deux points d'interrogation (??) indiquent qu'il s'agit d'un opérateur de coalescence.
L'opérateur de coalescence renvoie la première valeur NON NULL d'une chaîne. Vous pouvez voir cette vidéo sur youtube qui montre le tout dans sa globalité.
Mais laissez-moi ajouter plus à ce que dit la vidéo.
Si vous voyez que le sens anglais de coalescer signifie anglais, il est écrit «consolidate together». Par exemple, ci-dessous est un simple code coalescent qui chaîne quatre chaînes.
Donc, si str1
est null
, il tentera str2
, si str2
est null
, il tentera str3
et ainsi de suite jusqu'à ce qu'il trouve une chaîne avec une valeur non nulle.
string final = str1 ?? str2 ?? str3 ?? str4;
En mots simples L'opérateur Coalescing renvoie la première valeur NON NULL d'une chaîne.
Si vous connaissez Ruby, son ||=
me semble ressembler au ??
de C #. Voici quelques rubis:
irb(main):001:0> str1 = nil
=> nil
irb(main):002:0> str1 ||= "new value"
=> "new value"
irb(main):003:0> str2 = "old value"
=> "old value"
irb(main):004:0> str2 ||= "another new value"
=> "old value"
irb(main):005:0> str1
=> "new value"
irb(main):006:0> str2
=> "old value"
Et en C #:
string str1 = null;
str1 = str1 ?? "new value";
string str2 = "old value";
str2 = str2 ?? "another new value";
Rien de dangereux à ce sujet. En fait, c'est magnifique. Vous pouvez ajouter une valeur par défaut si cela est souhaitable, par exemple:
CODE
int x = x1 ?? x2 ?? x3 ?? x4 ?? 0;
C'est la main courte pour l'opérateur ternaire.
FormsAuth = (formsAuth != null) ? formsAuth : new FormsAuthenticationWrapper();
Ou pour ceux qui ne font pas ternaire:
if (formsAuth != null)
{
FormsAuth = formsAuth;
}
else
{
FormsAuth = new FormsAuthenticationWrapper();
}
opérateur de coalescence
c'est équivalent à
FormsAuth = formsAUth == null ? new FormsAuthenticationWrapper() : formsAuth
Pour votre amusement uniquement (sachant que vous êtes tous des gars C # ;-).
Je pense que cela provient de Smalltalk, où il existe depuis de nombreuses années. Il est défini ici comme:
en objet:
? anArgument
^ self
dans UndefinedObject (classe de nil):
? anArgument
^ anArgument
Il existe des versions évaluant (?) Et non évaluant (??) de this.
On le trouve souvent dans les méthodes getter pour les variables privées (d'instance) initialisées paresseux, qui sont laissées nuls jusqu'à ce qu'elles soient réellement nécessaires.
Certains exemples d’obtention de valeurs utilisant la fusion sont inefficaces.
Ce que vous voulez vraiment, c'est:
return _formsAuthWrapper = _formsAuthWrapper ?? new FormsAuthenticationWrapper();
ou
return _formsAuthWrapper ?? (_formsAuthWrapper = new FormsAuthenticationWrapper());
Cela empêche l'objet d'être recréé à chaque fois. Au lieu que la variable privée reste null et qu'un nouvel objet soit créé à chaque demande, cela garantit que la variable privée est affectée si le nouvel objet est créé.
Comme indiqué à juste titre dans de nombreuses réponses, il s'agit de "l'opérateur de fusion nul" (??), dont vous pouvez également consulter le cousin, l '"opérateur Null-conditionnel" (? _ ou ? [) qui est un opérateur qui est souvent utilisé conjointement avec ??
Utilisé pour tester la valeur null avant d'effectuer une opération d'accès membre (?.) Ou d'index (? [). Ces opérateurs vous aident à écrire moins de code pour gérer les contrôles NULL, en particulier pour la descente dans les structures de données.
Par exemple:
// if 'customers' or 'Order' property or 'Price' property is null,
// dollarAmount will be 0
// otherwise dollarAmount will be equal to 'customers.Order.Price'
int dollarAmount = customers?.Order?.Price ?? 0;
l'ancienne manière sans ?. et ?? de le faire est
int dollarAmount = customers != null
&& customers.Order!=null
&& customers.Order.Price!=null
? customers.Order.Price : 0;
ce qui est plus verbeux et encombrant.
J'ai lu tout ce fil et bien d'autres, mais je ne trouve pas de réponse aussi complète que celle-ci.
Par ce que j'ai complètement compris le "pourquoi utiliser ?? et quand utiliser ?? et comment utiliser ??."
La fondation de communication Windows libérée par Craig McMurtry ISBN 0-672-32948-4
Il existe deux circonstances courantes dans lesquelles on souhaiterait savoir si Une valeur a été affectée à une instance d'un type de valeur. Le premier est lorsque l'instance représente une valeur dans une base de données. Dans un tel cas, on voudrait pouvoir examiner l'instance pour vérifier si une valeur est effectivement présente dans la base de données. L'autre circonstance, qui est plus pertinente pour le sujet de ce livre, est lorsque l'instance représente un élément de données reçu d'une source distante. Là encore, on souhaiterait déterminer à partir de l'instance si une valeur pour cet élément de données a été reçue.
Le .NET Framework 2.0 incorpore une définition de type générique qui fournit des cas comme ceux-ci dans lesquels on veut affecter null à une instance d'un type valeur et tester si la valeur de l'instance est null. Cette définition de type générique est System.Nullable, qui contraint les arguments de type génériques pouvant être substitués à T en types de valeur . Une valeur de null peut être affectée aux instances de types construites à partir de System.Nullable. en effet, leurs valeurs sont nulles par défaut. Ainsi, les types construits à partir de System.Nullable peuvent être appelés types à valeur nullable System.Nullable a une propriété, Value, par laquelle la valeur affectée à une instance de Un type construit à partir de celle-ci peut être obtenu si la valeur de l'instance n'est pas null . On peut donc écrire:
System.Nullable<int> myNullableInteger = null;
myNullableInteger = 1;
if (myNullableInteger != null)
{
Console.WriteLine(myNullableInteger.Value);
}
Le langage de programmation C # fournit une syntaxe abrégée pour la déclaration des types Construite à partir de System.Nullable. Cette syntaxe permet d'abréger:
System.Nullable<int> myNullableInteger;
à
int? myNullableInteger;
Le compilateur empêchera quelqu'un d'essayer d'affecter la valeur d'un type de valeur nullable à un type de valeur ordinaire de la manière suivante:
int? myNullableInteger = null;
int myInteger = myNullableInteger;
Cela empêche personne de le faire car le type de valeur nullable pourrait avoir la valeur null, ce qu'il aurait en réalité dans ce cas, et cette valeur ne peut pas être affectée à un type de valeur ordinaire. Bien que le compilateur permette ce code,
int? myNullableInteger = null;
int myInteger = myNullableInteger.Value;
La deuxième instruction provoquerait une exception, car toute tentative d'accéder à la propriété System.Nullable.Value est une opération non valide si le type .__ construit à partir de System.Nullable n'a pas reçu de valeur valide T, ce qui n'est pas arrivé dans ce cas.
Une méthode appropriée pour affecter la valeur d'un type de valeur nullable à un type de valeur ordinaire consiste à utiliser la propriété System.Nullable.HasValue pour vérifier si une valeur valide de T a été affectée au type de valeur nullable:
int? myNullableInteger = null;
if (myNullableInteger.HasValue)
{
int myInteger = myNullableInteger.Value;
}
Une autre option consiste à utiliser cette syntaxe:
int? myNullableInteger = null;
int myInteger = myNullableInteger ?? -1;
Par lequel l'entier ordinaire myInteger se voit attribuer la valeur de l'entier nullable "myNullableInteger" si ce dernier s'est vu attribuer une valeur entière valide; sinon, la valeur -1 est attribuée à myInteger.
L'opérateur ??
s'appelle l'opérateur null-coalescing. Il renvoie l'opérande de gauche si l'opérande n'est pas nul; sinon, il retourne l'opérande de droite.
int? variable1 = null;
int variable2 = variable1 ?? 100;
Définissez variable2
sur la valeur variable1
, si variable1
est NON, null, sinon, si variable1 == null
, définissez variable2
sur 100.
C'est un opérateur de coalescence nul qui fonctionne de la même manière qu'un opérateur ternaire.
a ?? b => a !=null ? a : b
"Un type nullable peut contenir une valeur ou il peut être indéfini" . Donc, si vous essayez d'affecter un type valeur nullable à un type valeur non nullable vous obtiendrez une erreur de compilation.
int? x = null; // x is nullable value type
int z = 0; // z is non-nullable value type
z = x; // compile error will be there.
Alors faire ça en utilisant ?? opérateur:
z = x ?? 1; // with ?? operator there are no issues
FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();
est équivalent à
FormsAuth = formsAuth != null ? formsAuth : new FormsAuthenticationWrapper();
Mais l’avantage, c’est que vous pouvez les enchaîner, comme d’autres personnes l’ont dit ... La seule chose qui n’a pas été abordée, c’est que vous pouvez l’utiliser pour lancer une exception.
A = A ?? B ?? throw new Exception("A and B are both NULL");