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