Ces deux lignes sont-elles les mêmes? … :’ contre ‘??’?

Y a-t-il une différence entre ces deux lignes?

MyName = (s.MyName == null) ? ssortingng.Empty : s.MyName 

ou

 MyName = s.MyName ?? ssortingng.Empty 

MISE À JOUR: J’ai écrit un article de blog qui traite de ce sujet de manière plus approfondie. http://www.codeducky.org/properties-fields-and-methods-oh-my/


Généralement, ils retourneront le même résultat. Cependant, il existe quelques cas où vous rencontrerez des différences notables lorsque MyName est une propriété car le getter MyName sera exécuté deux fois dans le premier exemple et une seule fois dans le deuxième exemple.

Par exemple, vous pouvez rencontrer des différences de performances lors de l’exécution de MyName deux fois:

 ssortingng MyName { get { Thread.Sleep(10000); return "HELLO"; } } 

Ou vous pouvez obtenir des résultats différents en exécutant MyName deux fois si MyName est stateful:

 private bool _MyNameHasBeenRead = false; ssortingng MyName { get { if(_MyNameHasBeenRead) throw new Exception("Can't read MyName twice"); _MyNameHasBeenRead = true; Thread.Sleep(10000); return "HELLO"; } } 

Vous pouvez également obtenir des résultats différents en exécutant MyName deux fois si MyName peut être modifié sur un thread différent:

 void ChangeMyNameAsync() { //MyName set to null in another thread which makes it //possible for the first example to return null Task.Run(() => this.MyName = null); } ssortingng MyName { get; set; } 

Voici comment le code est compilé. D’abord le morceau avec l’expression ternaire:

 IL_0007: ldloc.0 // s IL_0008: callvirt s.get_MyName <-- first call IL_000D: brfalse.s IL_0017 IL_000F: ldloc.0 // s IL_0010: callvirt s.get_MyName <-- second call IL_0015: br.s IL_001C IL_0017: ldsfld System.String.Empty IL_001C: call set_MyName 

et voici le morceau avec l'opérateur null-coalescer:

 IL_0007: ldloc.0 // s IL_0008: callvirt s.get_MyName <-- only call IL_000D: dup IL_000E: brtrue.s IL_0016 IL_0010: pop IL_0011: ldsfld System.String.Empty IL_0016: call s.set_MyName 

Comme vous pouvez le voir, le code compilé pour l'opérateur ternaire fera deux appels pour obtenir la valeur de la propriété, tandis que l'opérateur null-coalescer ne le fera que 1.

Si la propriété est plus qu’un simple getter, vous pouvez exécuter une fonction deux fois dans le cas non nul pour le premier.

Si la propriété se trouve dans un object avec état, le deuxième appel à la propriété peut renvoyer un résultat différent:

 class MyClass { private IEnumerator _next = Next(); public MyClass() { this._next.MoveNext(); } public ssortingng MyName { get { var n = this._next.Current; this._next.MoveNext(); return n; } } public static IEnumerator Next() { yield return "foo"; yield return "bar"; } } 

De plus, dans le cas non-ssortingng, la classe peut surcharger == pour faire quelque chose de différent de l’opérateur ternaire. Je ne crois pas que l’opérateur ternaire puisse être surchargé.

La seule différence est de savoir si vous évaluez s.MyName deux ou une fois. Le premier le fera deux fois dans le cas où s.MyName n’est pas nul, le second ne l’évaluera qu’une seule fois.

Dans la plupart des cas, cette différence n’a pas d’importance et j’irais avec le second parce que c’est plus clair et concis.

Oui, les deux sont les mêmes, et il s’agit de l’ opérateur de coalescence nulle .

Il retourne l’opérande de gauche si l’opérande n’est pas nul; sinon, il retourne l’opérande de la main droite.

Si on parle d’efficacité, alors

 ssortingng MyName = (s.MyName == null) ? ssortingng.Empty : s.MyName; ssortingng MyName2 = s.MyName ?? ssortingng.Empty; 

Si j’utilise un dissembleur, je peux voir que la première instruction a besoin de 19 instructions pour être exécutée par le compilateur, tandis que la deuxième instruction nécessite seulement 12 instructions à exécuter.

Oui, ils font la même chose. ?? est un raccourci pour rechercher null.

Ils accomplissent la même tâche.

La seule différence serait la lisibilité quant à savoir si vos collègues ou quiconque lit le code comprend la syntaxe.

EDIT: En outre, la première option peut évaluer la propriété MyName deux fois.

Non, les deux font la même chose. Le second est efficace. Qui renvoie la valeur réelle si elle n’est pas nulle. Sinon, la valeur du côté droit sera renvoyée.

Référer ceci http://msdn.microsoft.com/en-us/library/ms173224.aspx

J’espère que cela t’aides.