Sé que la forma estándar de usar el operador de fusión nula en C # es establecer valores predeterminados.
string nobody = null;
string somebody = "Bob Saget";
string anybody = "";
anybody = nobody ?? "Mr. T"; // returns Mr. T
anybody = somebody ?? "Mr. T"; // returns "Bob Saget"
¿Pero para qué más se ??
puede usar? No parece tan útil como el operador ternario, aparte de ser más conciso y más fácil de leer que:
nobody = null;
anybody = nobody == null ? "Bob Saget" : nobody; // returns Bob Saget
Entonces, dado que pocos saben siquiera sobre el operador de fusión nula ...
¿Has usado
??
para otra cosa?Es
??
necesario, o simplemente debe usar el operador ternario (con el que la mayoría está familiarizado)
c#
coding-style
null
conditional-operator
null-coalescing-operator
Armstrongest
fuente
fuente
Lo he usado como una línea de carga perezosa:
¿Legible? Decide por ti mismo.
fuente
Lo he encontrado útil en dos formas "ligeramente extrañas":
out
parámetro al escribirTryParse
rutinas (es decir, devolver el valor nulo si falla el análisis)Este último necesita un poco más de información. Por lo general, cuando crea una comparación con múltiples elementos, debe ver si la primera parte de la comparación (por ejemplo, edad) da una respuesta definitiva, luego la siguiente parte (por ejemplo, nombre) solo si la primera parte no ayudó. El uso del operador de fusión nula significa que puede escribir comparaciones bastante simples (ya sea para ordenar o para igualdad). Por ejemplo, usando un par de clases auxiliares en MiscUtil :
Es cierto que ahora tengo ProjectionComparer en MiscUtil, junto con algunas extensiones, que hacen que este tipo de cosas sea aún más fácil, pero aún está ordenado.
Se puede hacer lo mismo para verificar la igualdad de referencia (o nulidad) al comienzo de la implementación de Equals.
fuente
Otra ventaja es que el operador ternario requiere una doble evaluación o una variable temporal.
Considere esto, por ejemplo:
mientras que con el operador ternario te quedan:
que llama a MyMethod dos veces, o:
De cualquier manera, el operador de fusión nula es más limpio y, supongo, más eficiente.
fuente
MyMethod()
tienen algún tipo de efectos secundarios.MyMethod()
no tiene ningún efecto fuera de devolver un valor, el compilador sabe que no debe llamarlo dos veces, por lo que realmente no tiene que preocuparse por la eficiencia aquí en la mayoría de los casos.MyMethod()
trata de una secuencia encadenada de objetos punteados. Ej:myObject.getThing().getSecondThing().getThirdThing()
MyMethod
son idénticas en este contexto, suponiendo queMyMethod
sea una función Pura. Otra opción es la memorización automática o simplemente tener la función cerrada en caché. Por otro lado: en.wikipedia.org/wiki/Global_value_numberingOtra cosa a considerar es que el operador de fusión no llama al método get de una propiedad dos veces, como lo hace el ternario.
Así que hay escenarios en los que no deberías usar ternary, por ejemplo:
Si utiliza:
el getter se llamará dos veces y la
count
variable será igual a 2, y si usa:la
count
variable será igual a 1, como debería ser.fuente
??
es equivalente a?:
.La mayor ventaja que encuentro para el
??
operador es que puede convertir fácilmente los tipos de valores anulables en tipos no anulables:Frecuentemente uso esto en consultas de Linq:
fuente
kvp == null
. Y en realidadNullable<T>
tiene unGetValueOrDefault
método que normalmente uso.He usado ?? en mi implementación de IDataErrorInfo:
Si alguna propiedad individual está en estado de "error", obtengo ese error; de lo contrario, obtengo un valor nulo. Funciona muy bien
fuente
this["Name"]
,this["Address"]
, etc ??Puede usar el operador de fusión nula para que sea un poco más limpio manejar el caso en el que no se establece un parámetro opcional:
fuente
arg ?= Arg.Default
?Me gusta usar el operador de fusión nula para cargar de forma diferida ciertas propiedades.
Un ejemplo muy simple (y artificial) solo para ilustrar mi punto:
fuente
En realidad, mi experiencia es que muy pocas personas están familiarizadas con el operador ternario (o más correctamente, el operador condicional ;
?:
es "ternario" en el mismo sentido que||
es binario o+
es unario o binario; sin embargo, resulta ser el solo operador ternario en muchos idiomas), por lo que al menos en esa muestra limitada, su declaración falla allí mismo.Además, como se mencionó anteriormente, hay una situación importante en la que el operador de fusión nula es muy útil, y es cuando la expresión a evaluar tiene algún efecto secundario. En ese caso, no puede usar el operador condicional sin (a) introducir una variable temporal o (b) cambiar la lógica real de la aplicación. (b) claramente no es apropiado en ninguna circunstancia, y si bien es una preferencia personal, no me gusta saturar el alcance de la declaración con muchas variables extrañas, incluso si son de corta duración, por lo que (a) también está fuera de lugar Escenario particular.
Por supuesto, si necesita hacer varias verificaciones sobre el resultado, el operador condicional, o un conjunto de
if
bloques, es probablemente la herramienta para el trabajo. Pero para el simple "si esto es nulo, úselo, de lo contrario úselo", el operador de fusión nulo??
es perfecto.fuente
Una cosa que he estado haciendo mucho últimamente es usar la fusión nula para hacer copias de seguridad
as
. Por ejemplo:También es útil para hacer una copia de seguridad de largas cadenas
?.
que podrían fallarfuente
El único problema es que el operador de fusión nula no detecta cadenas vacías.
es decir
SALIDA:
Actualmente estoy buscando anular el ?? operador para evitar esto. Seguro que sería útil tener esto integrado en el Marco.
Pensamientos?
fuente
??
no se puede sobrecargar: msdn.microsoft.com/en-us/library/8edha89s(v=vs.100).aspx ; sin embargo, sería genial tenerlo sobrecargado. Yo uso una combinación:s1.Nullify() ?? s2.Nullify()
dondestring Nullify(this s)
devuelve unnull
en casos cuando la cadena está vacía.Debe usar lo que mejor exprese su intención. Dado que no es un operador se unen nula, usarlo .
Por otro lado, como es tan especializado, no creo que tenga otros usos. Hubiera preferido una sobrecarga adecuada del
||
operador, como lo hacen otros idiomas. Esto sería más parsimonioso en el diseño del lenguaje. Pero bueno …fuente
¡Frio! Contarme como alguien que no sabía sobre el operador de fusión nula, es algo bastante ingenioso.
Me resulta mucho más fácil de leer que el operador ternario.
El primer lugar que me viene a la mente donde podría usarlo es mantener todos mis parámetros predeterminados en un solo lugar.
fuente
Es un caso de uso un poco extraño, pero tenía un método en el que un
IDisposable
objeto se pasa potencialmente como un argumento (y, por lo tanto, está dispuesto por el padre), pero también podría ser nulo (por lo que debería crearse y eliminarse en el método local)Para usarlo, el código parecía
Pero con una fusión nula se vuelve mucho más ordenada
fuente
He usado así:
fuente