usar unario una sharp question operator operadores operador mark linea jerarquia como c# .net nullable c#-6.0 null-conditional-operator

c# - unario - ¿El operador “?.” Hace algo más aparte de verificar si está nulo?



operador if (3)

Considerando:

DateTime? dt = DateTime.Now; string x; if(dt != null) x = dt.ToString("dd/MM/yyyy");

Aquí dt es un DateTime? o Nullable<DateTime> witch no es IFormatable y no tiene un ToString(string format) .

Así que tirar.

Ahora considerando:

x = dt?.ToString("dd/MM/yyyy");

El ?. Es un azúcar sintáctico para:

dt.HasValue ? dt.Value.ToString("dd/MM/yyyy"): null

Aquí dt.Value es un DateTime que es IFormatable y tiene un ToString(string format) .

Finalmente, la buena manera de escribir el primer código en C # 5.0 es:

DateTime? dt = DateTime.Now; string x; if(dt.HasValue) x = dt.Value.ToString("dd/MM/yyyy");

Como sabrás, DateTime? no tiene un ToString parametrizado (a los efectos de formatear la salida), y hacer algo como

DateTime? dt = DateTime.Now; string x; if(dt != null) x = dt.ToString("dd/MM/yyyy");

tirará

Ninguna sobrecarga para el método ''ToString'' toma 1 argumentos

Pero, desde C # 6.0 y el operador Elvis ( ?. ), El código anterior se puede reemplazar con

x = dt?.ToString("dd/MM/yyyy");

que .... funciona! ¿Por qué?


Debido a que Nullable<T> se implementa en C # de una manera que hace que las instancias de esa estructura aparezcan como tipos anulables. Cuando tienes DateTime? en realidad es Nullable<DateTime> , cuando asigna null a eso, establece HasValue en false detrás de escena, cuando verifica null , está verificando HasValue , etc. el operador se implementa de manera tal que reemplaza los mismos modismos que funcionan para tipos de referencia también para estructuras anulables. Al igual que el resto del lenguaje, las estructuras anulables son similares a los tipos de referencia (con respecto a la null ).


Respuesta corta:

DateTime? es solo una sintaxis dulce para Nullable<DateTime> que no contiene las propiedades y el método de DateTime , mientras que el operador de Elvis funciona en el valor no válido de Nullable<DateTime>.Value .

Explicación:

El siguiente código:

DateTime? dt = DateTime.Now; string x; if (dt != null) x = dt?.ToString("dd/MM/yyyy");

Cuando se descompila como C# 5.0 obtiene el siguiente resultado:

DateTime? nullable = new DateTime?(DateTime.Now); if (nullable.HasValue) { string str = nullable.HasValue ? nullable.GetValueOrDefault().ToString("dd/MM/yyyy") : null; }

Nota al margen: la string parece declarada dentro de if es irrelevante debido a la elevación en el nivel de MSIL , y dado que el valor no se usa más adelante, el descompilador lo muestra como si hubiera sido declarado dentro de ese alcance.

Como ves, y desde DateTime? es solo una sintaxis dulce para Nullable<DateTime> , C# tiene una referencia específica para Nullable<T> s con el operador Elvis , haciendo que su valor de retorno sea la T no anulable .

El resultado de todo el Elvis operator debe ser Nullable , por Nullable tanto, si desea recibir un valor no de string , debe ser Nullable<T> o un ReferenceType pero esto no cambia el hecho de que si el operador ha logrado obtenga el Nullable<DateTime> sí mismo - DateTime devuelto ya no es Nullable<DateTime> .