c# - significa - signo de interrogacion en programacion




¿Qué significan dos signos de interrogación juntos en C#? (11)

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.


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 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;

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.


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 ().


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");






null-coalescing-operator