"Evalúe el primer operando; si es nulo, deténgase, con un resultado de nulo. De lo contrario, evalúe el segundo operando (como acceso de miembro del primer operando)".
En su ejemplo, el punto es que si aes así null, entonces a?.PropertyOfAevaluará en nulllugar de lanzar una excepción; luego comparará esa nullreferencia con foo(usando la ==sobrecarga de la cadena ), encontrará que no son iguales y la ejecución irá al cuerpo delif declaración .
En otras palabras, es así:
string bar =(a ==null?null: a.PropertyOfA);if(bar != foo){...}
... excepto que asolo se evalúa una vez.
Tenga en cuenta que esto también puede cambiar el tipo de expresión. Por ejemplo, considere FileInfo.Length. Esa es una propiedad de tipo long, pero si la usa con el operador condicional nulo, termina con una expresión de tipo long?:
FileInfo fi =...;// fi could be nulllong? length = fi?.Length;// If fi is null, length will be null
@SLaks: pensé que era "nulo condicional" pero podría estar equivocado. La última vez que revisé los documentos de características del idioma Roslyn, tampoco había cambiado el nombre. Tal vez la fuente es la autoridad aquí, lo comprobará.
Jon Skeet
3
@SLaks: Claro. En SyntaxKind aparentemente es ConditionalAccessExpression, lo cual es molesto para ninguno de ellos ...
Jon Skeet
12
prefiero el nombre de operador "Elvis": P
Ahmed ilyas
3
Solo para el registro, he visto cinco nombres diferentes para este operador: navegación segura, condicional nulo, propagación nula, acceso condicional, Elvis.
Gigi
81
Puede ser muy útil al acoplar una jerarquía y / o asignar objetos. En vez de:
Para salvar a las personas que buscan qué? es .. Es el operador de fusión nula y devolverá Nombre si no es nulo, de lo contrario devolverá "N / A".
Steve
66
@Erik Philips Creo que es necesario agregar || Model.Model2.Model3.Model4.Name == null a tener la misma lógica, si no en caso Model.Model2.Model3.Model4.Namees null, mapped.Namepermaneceránull
RazvanR
2
@ ErikPhilips No en la misma página, supongo. Intente ver qué sucede en ambos casos, si Model.Model2.Model3.Model4.Namees así null.
@ErikPhilips: Eso no tiene nada que ver con el primer comentario, ya que esto no se relaciona con su primer ejemplo. En esto, saltarías a la elserama y tendrías mapped.Name = Model.Model2.Model3.Model4.Name -> mapped.Name = null, mientras que tu segundo ejemplo lo sustituiría mapped.Name = "N/A". Vea el DotNetFiddle editado
derM
3
Esto es relativamente nuevo en C #, lo que nos facilita llamar las funciones con respecto a nulo o no nulo valores en el encadenamiento de métodos.
La vieja forma de lograr lo mismo era:
var functionCaller =this.member;if(functionCaller!=null)
functionCaller.someFunction(var someParam);
Puede ser muy útil al acoplar una jerarquía y / o asignar objetos. En vez de:
Se puede escribir como (la misma lógica que la anterior)
DotNetFiddle.Net Ejemplo de trabajo .
(el operador ?? o nulo-coalescente es diferente del operador condicional? o nulo ).
También se puede usar fuera de los operadores de asignación con Action. En vez de
Se puede simplificar para:
Ejemplo de DotNetFiddle :
utilizando el sistema;
Resultado:
fuente
|| Model.Model2.Model3.Model4.Name == null
a tener la misma lógica, si no en casoModel.Model2.Model3.Model4.Name
esnull
,mapped.Name
permaneceránull
Model.Model2.Model3.Model4.Name
es asínull
.else
rama y tendríasmapped.Name = Model.Model2.Model3.Model4.Name -> mapped.Name = null
, mientras que tu segundo ejemplo lo sustituiríamapped.Name = "N/A"
. Vea el DotNetFiddle editadoEsto es relativamente nuevo en C #, lo que nos facilita llamar las funciones con respecto a nulo o no nulo valores en el encadenamiento de métodos.
La vieja forma de lograr lo mismo era:
y ahora se ha hecho mucho más fácil con solo:
Le recomiendo que lo lea aquí:
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/null-conditional-operators
fuente