La nula operador coalesce es mucho más claro en la comprobación de null, que es su propósito principal. También puede ser encadenado.
object a = null;
object b = null;
object c = new object();
object d = a ?? b ?? c; //d == c.
Mientras que el operador se limita a null comprobación, el operador ternario es no. Por ejemplo
bool isQuestion = true;
string question = isQuestion ? "Yes" : "No";
creo que la gente simplemente no son conscientes de que el operador nulo se unen así que utilizan el operador ternario en su lugar. ternario existía antes de C# en la mayoría de lenguajes de estilo C por lo que si usted no sabe C# en el interior y fuera y/o programado en otro idioma, te rnary es una elección natural. Sin embargo, si está buscando un valor nulo, use el operador nulo coalesce, está diseñado para eso, y el IL está ligeramente optimizado (compare con un if si no con otro).
Este es un ejemplo que compara el uso de cada
object a = null;
object b = null;
object c = null;
object nullCoalesce = a ?? b ?? c;
object ternary = a != null ? a : b != null ? b : c;
object ifThenElse;
if (a != null)
ifThenElse = a;
else if (b != null)
ifThenElse = b;
else if (c != null)
ifThenElse = c;
En primer lugar, basta con ver la sintaxis de coalescencia nulo, que es la forma más clara. Ternary es realmente confuso. Ahora veamos la IL
nulo Coalesce Sólo
.entrypoint
.maxstack 2
.locals init (
[0] object a,
[1] object b,
[2] object c,
[3] object nullCoalesce)
L_0000: ldnull
L_0001: stloc.0
L_0002: ldnull
L_0003: stloc.1
L_0004: newobj instance void [mscorlib]System.Object::.ctor()
L_0009: stloc.2
L_000a: ldloc.0
L_000b: dup
L_000c: brtrue.s L_0015
L_000e: pop
L_000f: ldloc.1
L_0010: dup
L_0011: brtrue.s L_0015
L_0013: pop
L_0014: ldloc.2
L_0015: stloc.3
L_0016: ldloc.3
L_0017: call void [mscorlib]System.Console::WriteLine(object)
L_001c: ret
ternario Sólo
.entrypoint
.maxstack 2
.locals init (
[0] object a,
[1] object b,
[2] object c,
[3] object ternary)
L_0000: ldnull
L_0001: stloc.0
L_0002: ldnull
L_0003: stloc.1
L_0004: newobj instance void [mscorlib]System.Object::.ctor()
L_0009: stloc.2
L_000a: ldloc.0
L_000b: brtrue.s L_0016
L_000d: ldloc.1
L_000e: brtrue.s L_0013
L_0010: ldloc.2
L_0011: br.s L_0017
L_0013: ldloc.1
L_0014: br.s L_0017
L_0016: ldloc.0
L_0017: stloc.3
L_0018: ldloc.3
L_0019: call void [mscorlib]System.Console::WriteLine(object)
L_001e: ret
si entonces si no Sólo
.entrypoint
.maxstack 1
.locals init (
[0] object a,
[1] object b,
[2] object c,
[3] object ifThenElse)
L_0000: ldnull
L_0001: stloc.0
L_0002: ldnull
L_0003: stloc.1
L_0004: newobj instance void [mscorlib]System.Object::.ctor()
L_0009: stloc.2
L_000a: ldloc.0
L_000b: brfalse.s L_0011
L_000d: ldloc.0
L_000e: stloc.3
L_000f: br.s L_001a
L_0011: ldloc.1
L_0012: brfalse.s L_0018
L_0014: ldloc.1
L_0015: stloc.3
L_0016: br.s L_001a
L_0018: ldloc.2
L_0019: stloc.3
L_001a: ldloc.3
L_001b: call void [mscorlib]System.Console::WriteLine(object)
L_0020: ret
IL no es uno de mis puntos fuertes, así que quizás alguien pueda editar mi respuesta y expandirla. Iba a explicar mi teoría, pero preferiría no confundirme a mí mismo y a los demás. El número de LOC es similar para los tres, pero no todos los operadores de IL tardan el mismo tiempo en ejecutarse.
Una de las razones es que ppl podría no ser consciente. – vpram86
debería ser "var res = (data! = Null)? Data: new data();" en su muestra –
@Rubens, simplemente tonto y no está bien. – kenny