signo significa que programacion interrogacion doble con c# null-coalescing-operator

que - ¿Qué significan dos signos de interrogación juntos en C#?



que significa en c# (16)

Nota:

He leído todo este hilo y muchos otros, pero no puedo encontrar una respuesta tan completa como esta.

Por lo que entendí completamente el "por qué usar" y cuándo usar "y cómo usar".

Fuente:

Fundación de comunicación de Windows desatada por Craig McMurtry ISBN 0-672-32948-4

Tipos de valores anulables

Hay dos circunstancias comunes en las que a uno le gustaría saber si un valor se ha asignado a una instancia de un tipo de valor. La primera es cuando la instancia representa un valor en una base de datos. En tal caso, uno desearía poder examinar la instancia para determinar si un valor está realmente presente en la base de datos. La otra circunstancia, que es más pertinente al tema de este libro, es cuando la instancia representa un elemento de datos recibido de alguna fuente remota. Nuevamente, uno desearía determinar a partir de la instancia si se recibió un valor para ese elemento de datos.

.NET Framework 2.0 incorpora una definición de tipo genérico que proporciona casos como estos en los que se quiere asignar nulo a una instancia de un tipo de valor y probar si el valor de la instancia es nulo. Esa definición de tipo genérico es System.Nullable, que restringe los argumentos de tipo genérico que pueden sustituirse por T para valorar los tipos. A las instancias de tipos construidos desde System.Nullable se les puede asignar un valor nulo; De hecho, sus valores son nulos por defecto. Por lo tanto, los tipos construidos a partir de System.Nullable pueden denominarse tipos de valores que admiten valores nulos. System.Nullable tiene una propiedad, Valor, por la cual el valor asignado a una instancia de un tipo construido a partir de él puede obtenerse si el valor de la instancia no es nulo. Por lo tanto, uno puede escribir:

System.Nullable<int> myNullableInteger = null; myNullableInteger = 1; if (myNullableInteger != null) { Console.WriteLine(myNullableInteger.Value); }

El lenguaje de programación C # proporciona una sintaxis abreviada para declarar tipos construidos desde System.Nullable. Esa sintaxis nos permite abreviar:

System.Nullable<int> myNullableInteger;

a

int? myNullableInteger;

El compilador evitará que uno intente asignar el valor de un tipo de valor anulable a un tipo de valor ordinario de esta manera:

int? myNullableInteger = null; int myInteger = myNullableInteger;

Evita que uno lo haga porque el tipo de valor que puede contener nulos podría tener el valor nulo, que en realidad tendría en este caso, y ese valor no se puede asignar a un tipo de valor ordinario. Aunque el compilador permitiría este código,

int? myNullableInteger = null; int myInteger = myNullableInteger.Value;

La segunda declaración provocaría que se produjera una excepción porque cualquier intento de acceder a la propiedad System.Nullable.Value es una operación no válida si al tipo construido a partir de System.Nullable no se le ha asignado un valor válido de T, que no ha ocurrido en este caso.

Conclusión:

Una forma adecuada de asignar el valor de un tipo de valor que acepta valores nulos a un tipo de valor ordinario es usar la propiedad System.Nullable.HasValue para determinar si se ha asignado un valor válido de T al tipo de valor que acepta valores nulos:

int? myNullableInteger = null; if (myNullableInteger.HasValue) { int myInteger = myNullableInteger.Value; }

Otra opción es usar esta sintaxis:

int? myNullableInteger = null; int myInteger = myNullableInteger ?? -1;

Por el cual al entero ordinario myInteger se le asigna el valor del entero anulable "myNullableInteger" si a este último se le ha asignado un valor entero válido; de lo contrario, a myInteger se le asigna el valor de -1.

Corrió a través de esta línea de código:

FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();

¿Qué significan los dos signos de interrogación, es algún tipo de operador ternario? Es difícil buscar en Google.


Algunos de los ejemplos aquí de obtener valores utilizando coalescencia son ineficientes.

Lo que realmente quieres es:

return _formsAuthWrapper = _formsAuthWrapper ?? new FormsAuthenticationWrapper();

o

return _formsAuthWrapper ?? (_formsAuthWrapper = new FormsAuthenticationWrapper());

Esto evita que el objeto sea recreado cada vez. En lugar de que la variable privada quede nula y se cree un nuevo objeto en cada solicitud, esto garantiza que la variable privada se asigna si se crea el nuevo objeto.


Como señala correctamente en numerosas respuestas, este es el "operador de unión nula" ( ?? ), hablando de lo que también podría querer ver a su primo el "Operador condicional nulo" ( ?. O ? [ ) Que es un operador que muchas veces se utiliza junto con ??

Operador condicional nulo

Se utiliza para probar el valor nulo antes de realizar una operación de acceso de miembro ( ?. ) O índice ( ? [ ). Estos operadores lo ayudan a escribir menos código para manejar las comprobaciones nulas, especialmente para descender a las estructuras de datos.

Por ejemplo:

// if ''customers'' or ''Order'' property or ''Price'' property is null, // dollarAmount will be 0 // otherwise dollarAmount will be equal to ''customers.Order.Price'' int dollarAmount = customers?.Order?.Price ?? 0;

la vieja manera sin ? y ?? de hacer esto es

int dollarAmount = customers != null && customers.Order!=null && customers.Order.Price!=null ? customers.Order.Price : 0;

que es más detallado y engorroso.


Es el operador de unión nula, y muy parecido al operador ternario (inmediato-si). Véase también ?? Operador - MSDN .

FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();

se expande a:

FormsAuth = formsAuth != null ? formsAuth : new FormsAuthenticationWrapper();

que se expande a:

if(formsAuth != null) FormsAuth = formsAuth; else FormsAuth = new FormsAuthenticationWrapper();

En inglés, significa "Si lo que está a la izquierda no es nulo, use eso, de lo contrario use lo que está a la derecha".

Tenga en cuenta que puede utilizar cualquier número de estos en secuencia. La siguiente declaración asignará el primer Answer# de Answer no nulo a la Answer (si todas las respuestas son nulas, la Answer es nula):

string Answer = Answer1 ?? Answer2 ?? Answer3 ?? Answer4;

También vale la pena mencionar que si bien la expansión anterior es conceptualmente equivalente, el resultado de cada expresión solo se evalúa una vez. Esto es importante si, por ejemplo, una expresión es una llamada de método con efectos secundarios. (Gracias a @Joey por señalar esto).



Es mano corta para el operador ternario.

FormsAuth = (formsAuth != null) ? formsAuth : new FormsAuthenticationWrapper();

O para los que no hacen ternario:

if (formsAuth != null) { FormsAuth = formsAuth; } else { FormsAuth = new FormsAuthenticationWrapper(); }


Es un operador de unión nula que funciona de manera similar a un operador ternario.

a ?? b => a !=null ? a : b

Otro punto interesante para esto es: "Un tipo que puede contener nulos puede contener un valor, o puede ser indefinido" . Por lo tanto, si intenta asignar un tipo de valor anulable a un tipo de valor no anulable, obtendrá un error en tiempo de compilación.

int? x = null; // x is nullable value type int z = 0; // z is non-nullable value type z = x; // compile error will be there.

Así que para hacer eso usando ?? operador:

z = x ?? 1; // with ?? operator there are no issues


Gracias a todos, esta es la explicación más breve que encontré en el sitio de MSDN:

// y = x, unless x is null, in which case y = -1. int y = x ?? -1;


Nada peligroso sobre esto. De hecho, es hermoso. Puede agregar un valor predeterminado si es deseable, por ejemplo:

CÓDIGO

int x = x1 ?? x2 ?? x3 ?? x4 ?? 0;


Si estás familiarizado con Ruby, su ||= parece similar a C # ''s ?? a mi. Aquí hay un poco de Ruby:

irb(main):001:0> str1 = nil => nil irb(main):002:0> str1 ||= "new value" => "new value" irb(main):003:0> str2 = "old value" => "old value" irb(main):004:0> str2 ||= "another new value" => "old value" irb(main):005:0> str1 => "new value" irb(main):006:0> str2 => "old value"

Y en C #:

string str1 = null; str1 = str1 ?? "new value"; string str2 = "old value"; str2 = str2 ?? "another new value";


Solo para tu diversión (sabiendo que todos ustedes son chicos de C # ;-).

Creo que se originó en Smalltalk, donde ha existido durante muchos años. Se define allí como:

en objeto:

? anArgument ^ self

en UndefinedObject (también conocido como clase nil):

? anArgument ^ anArgument

Hay versiones de evaluación (?) Y no de evaluación (??) de esto.
A menudo se encuentra en métodos getter para variables privadas (instancia) perezosas inicializadas, que se dejan en cero hasta que realmente se necesitan.


Solo porque nadie más ha dicho las palabras mágicas todavía: es el operador de unión nula . Se define en la sección 7.12 de la especificación de lenguaje C # 3.0 .

Es muy útil, particularmente debido a la forma en que funciona cuando se usa varias veces en una expresión. Una expresión de la forma:

a ?? b ?? c ?? d

dará el resultado de la expresión a si no es nulo, de lo contrario intente b , de lo contrario intente c , de lo contrario intente d . Se cortocircuita en cada punto.

Además, si el tipo de d no es anulable, el tipo de la expresión completa tampoco es anulable.


operador coalescente

es equivalente a

FormsAuth = formsAUth == null ? new FormsAuthenticationWrapper() : formsAuth


?? está ahí para proporcionar un valor para un tipo anulable cuando el valor es nulo. Por lo tanto, si formsAuth es nulo, devolverá el nuevo FormsAuthenticationWrapper ().


Los dos signos de interrogación (??) indican que es un operador coalescente.

El operador coalescente devuelve el primer valor NON-NULL de una cadena. Puedes ver este video de youtube que demuestra todo el asunto prácticamente.

Pero déjame agregar más a lo que dice el video.

Si ve el significado en inglés de fusionarse, dice "consolidar juntos". Por ejemplo, a continuación hay un código de unión simple que encadena cuatro cadenas.

Entonces, si str1 es null , intentará con str2 , si str2 es null , intentará con str3 y así sucesivamente hasta que encuentre una cadena con un valor no nulo.

string final = str1 ?? str2 ?? str3 ?? str4;

En palabras simples, el operador coalescente devuelve el primer valor NON-NULL de una cadena.


FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();

es equivalente a

FormsAuth = formsAuth != null ? formsAuth : new FormsAuthenticationWrapper();

Pero lo bueno de esto es que puedes encadenarlos, como dijeron otras personas. Lo que no se menciona es que puedes usarlo para lanzar una excepción.

A = A ?? B ?? throw new Exception("A and B are both NULL");