Réponses:
C'est l' opérateur conditionnel nul . Cela signifie essentiellement:
"Évaluez le premier opérande; s'il est nul, arrêtez avec un résultat nul. Sinon, évaluez le deuxième opérande (en tant qu'accès membre du premier opérande)."
Dans votre exemple, le fait est que si a
est null
, alors a?.PropertyOfA
évaluera null
plutôt que de lever une exception - il comparera alors cette null
référence avec foo
(en utilisant la ==
surcharge de la chaîne ), trouvera qu'elles ne sont pas égales et l'exécution ira dans le corps de l' if
instruction .
En d'autres termes, c'est comme ça:
string bar = (a == null ? null : a.PropertyOfA);
if (bar != foo)
{
...
}
... sauf que cela a
n'est évalué qu'une seule fois.
Notez que cela peut également changer le type de l'expression. Par exemple, réfléchissez FileInfo.Length
. C'est une propriété de type long
, mais si vous l'utilisez avec l'opérateur conditionnel nul, vous vous retrouvez avec une expression de type long?
:
FileInfo fi = ...; // fi could be null
long? length = fi?.Length; // If fi is null, length will be null
Il peut être très utile lors de l'aplatissement d'une hiérarchie et / ou du mappage d'objets. Au lieu de:
if (Model.Model2 == null
|| Model.Model2.Model3 == null
|| Model.Model2.Model3.Model4 == null
|| Model.Model2.Model3.Model4.Name == null)
{
mapped.Name = "N/A"
}
else
{
mapped.Name = Model.Model2.Model3.Model4.Name;
}
Il peut être écrit comme (même logique que ci-dessus)
mapped.Name = Model.Model2?.Model3?.Model4?.Name ?? "N/A";
Exemple de travail DotNetFiddle.Net .
(l' opérateur ?? ou null-coalescing est différent de l' opérateur conditionnel? ou null ).
Il peut également être utilisé en dehors des opérateurs d'affectation avec Action. Au lieu de
Action<TValue> myAction = null;
if (myAction != null)
{
myAction(TValue);
}
Il peut être simplifié pour:
myAction?.Invoke(TValue);
en utilisant le système;
public class Program
{
public static void Main()
{
Action<string> consoleWrite = null;
consoleWrite?.Invoke("Test 1");
consoleWrite = (s) => Console.WriteLine(s);
consoleWrite?.Invoke("Test 2");
}
}
Résultat:
Test 2
|| Model.Model2.Model3.Model4.Name == null
à la même logique, sinon dans le cas Model.Model2.Model3.Model4.Name
est null
, mapped.Name
resteranull
Model.Model2.Model3.Model4.Name
est - null
.
else
sauteriez dans la branche-et avez mapped.Name = Model.Model2.Model3.Model4.Name -> mapped.Name = null
, tandis que votre deuxième exemple se substituerait à mapped.Name = "N/A"
. Voir l' édition DotNetFiddle
Ceci est relativement nouveau pour C #, ce qui nous permet d'appeler facilement les fonctions par rapport aux valeurs nulles ou non nulles dans le chaînage de méthode.
ancienne façon de réaliser la même chose était:
var functionCaller = this.member;
if (functionCaller!= null)
functionCaller.someFunction(var someParam);
et maintenant cela a été rendu beaucoup plus facile avec juste:
member?.someFunction(var someParam);
Je vous recommande fortement de le lire ici: