80 votes

Sont ces deux lignes identiques, ' ? ... : ' vs ' ?? ' ?

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

ou

166voto

Steven Wexler Points 4386

Mise à JOUR: j'ai écrit un post de blog qui traite de ce sujet plus en profondeur. http://www.codeducky.org/properties-fields-and-methods-oh-my/


Généralement ils seront de retour le même résultat. Cependant, il existe quelques cas où vous l'expérience des différences notables lors de l' MyName est un bien, car l' MyName de lecture sera exécuté à deux reprises dans le premier exemple, et seulement une fois dans le deuxième exemple.

Par exemple, vous pouvez rencontrer des différences de rendement de l'exécution d' MyName deux fois:

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

Ou vous pouvez obtenir des résultats différents de l'exécution d' MyName deux fois si MyName est dynamique:

private bool _MyNameHasBeenRead = false;

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

Ou vous pouvez obtenir des résultats différents de l'exécution d' MyName deux fois si MyName peut être modifié sur un autre thread:

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);
}

string MyName { get; set; }  

Voici comment le code est compilé. D'abord la pièce avec le ternaire de l'expression:

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 le null-coalescence de l'opérateur:

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 va faire deux appels pour obtenir la valeur de la propriété, tandis que le null-coalescence opérateur de seulement 1.

26voto

Dan Gallagher Points 608

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

Si la propriété est dans un objet dynamique, puis le deuxième appel à la propriété peut retourner un résultat différent :

En outre, dans le cas d’autre qu’une chaîne, 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 peut être surchargé.

9voto

Tim S. Points 30377

La seule différence est que vous évaluez deux ou une fois. Le premier va le faire deux fois dans le cas que est pas null, la seconde ne jamais l’évalueront une fois.

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

5voto

Sachin Points 19502

Oui, les deux sont le même, et c'est le null-coalescence de l'opérateur.

Il retourne la gauche opérande si l'opérande n'est pas nulle; sinon elle retourne la main droite opérande.

Si nous parlons de l'efficacité ensuite

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

Si j'utilise un dissembler ensuite, je peux voir que la première instruction besoins du 19 instructions à exécuter par le compilateur alors que la seconde déclaration requise seulement 12 instructions à exécuter.

0voto

Zdravko Danev Points 6156

Oui, ils font la même chose. ``est un raccourci pour la vérification des null.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X