¿El "?."operator hacer algo más aparte de la comprobación de null?
Como puede que sepas, DateTime?
no tiene un ToString
parametrizado (con el propósito de formatear la salida), y hacer algo como
DateTime? dt = DateTime.Now;
string x;
if(dt != null)
x = dt.ToString("dd/MM/yyyy");
Lanzará
Sin 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 por
x = dt?.ToString("dd/MM/yyyy");
Cuál.... funciona! ¿Por qué?
3 answers
Porque Nullable<T>
está implementado en C# de una manera que hace que las instancias de esa estructura aparezcan como tipos nullables. Cuando tienes DateTime?
es en realidad Nullable<DateTime>
, cuando asignas null
a eso, estás configurando HasValue
a false
detrás de escena, cuando compruebas null
, estás comprobando HasValue
, etc. El operador ?.
simplemente se implementa de manera que reemplaza los mismos modismos que funcionan para tipos de referencia también para estructuras nullables. Al igual que el resto del lenguaje hace estructuras nullables similar a los tipos de referencia (con respecto a null
- ness).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-29 10:29:57
respuesta Corta:
DateTime?
es solo una sintaxis dulce para Nullable<DateTime>
que no contiene las propiedades y el método de DateTime
mientras el operador Elvis trabaja en el not-Nullable 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
se 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: el string
parece declarado dentro del if
es irrelevante debido a la elevación en el nivel MSIL
, y dado que el valor no se utiliza más adelante, el descompilador lo muestra como si hubiera sido declarado dentro de ese ámbito if
.
Como ves, y dado que DateTime?
es solo una sintaxis dulce para Nullable<DateTime>
, C#
tiene una referencia específica para Nullable<T>
s con el operador de Elvis , haciendo su valor de retorno la propia T no anulable.
El resultado del conjunto Elvis operator
debe ser Nullable
por lo tanto, si desea recibir un valor no-string
tendría que ser Nullable<T>
o un ReferenceType
, pero esto no cambia el hecho de que si el operador ha logrado obtener el valor Nullable<DateTime>
por sí mismo, el DateTime
devuelto ya no es Nullable<DateTime>
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-01 07:45:45
Considerando:
DateTime? dt = DateTime.Now;
string x;
if(dt != null)
x = dt.ToString("dd/MM/yyyy");
Aquí dt
es una DateTime?
o Nullable<DateTime>
bruja no es IFormatable
y no tiene un método ToString(string format)
.
Así que tira.
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 una DateTime
bruja es IFormatable
y tiene un método 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");
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-29 10:44:54