27 votes

Est-ce que le "?." L'opérateur fait autre chose que la vérification de null?

Comme vous le savez peut-être, DateTime? n'a pas de ToString paramétré (à des fins de formatage de la sortie) et de faire quelque chose comme

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

jettera

Aucune surcharge pour la méthode 'ToString' prend 1 arguments

Mais, depuis C # 6.0 et l'opérateur Elvis ( ?. ), le code ci-dessus peut être remplacé par

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

qui .... fonctionne! Pourquoi?

19voto

Joey Points 148544

Parce qu' Nullable<T> est implémenté en C# d'une manière qui rend les instances de cette structure apparaissent comme des types nullables. Lorsque vous avez DateTime? c'est en fait Nullable<DateTime>, lorsque vous affectez null , vous êtes paramètre HasValue de false derrière les coulisses, lorsque vous vérifiez l' null, vous êtes en vérifiant HasValue, etc. L' ?. opérateur est juste mis en œuvre de manière qu'il remplace le très même les idiomes qui travaillent pour les types référence également pour nullable des structures. Tout comme le reste de la langue, c'est nullable des structures semblables à des types de référence (à l'égard null-ness).

14voto

Some1Pr0 Points 853

Réponse courte:

DateTime? n'est qu'un doux syntaxe pour Nullable<DateTime> qui ne contient pas d' DateTimes'propriétés et de la méthode alors que la Elvis opérateur travaille sur la non-Nullable Nullable<DateTime>.Value.


Explication:

Le code suivant:

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

Lors de la décompilation, comme C# 5.0 donne le résultat suivant:

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

Remarque: l' string semble déclarée à l'intérieur de l' if n'est pas pertinent parce que de brandir au MSIL de niveau, et comme la valeur n'est pas utilisée plus tard le decompiler montre comme si elle a été déclarée à l'intérieur qu' if de la portée.

Comme vous le voyez, et depuis DateTime? n'est qu'un doux syntaxe pour Nullable<DateTime>, C# a une référence spécifique pour l' Nullable<T>s avec le Elvis de l'opérateur, ce qui rend sa valeur de retour non nullable T lui-même.

Le résultat de l'ensemble de l' Elvis operator doit Nullable donc, si vous voulez recevoir un non-string de la valeur qu'il devrait être Nullable<T> ou ReferenceType mais cela ne change pas le fait que si l'opérateur a réussi à obtenir l' Nullable<DateTime> la valeur elle-même - le retour de l' DateTime n'est Nullable<DateTime> plus.

2voto

Orace Points 31

Considérant:

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

Ici, dt est DateTime? ou Nullable<DateTime> de sorcière n'est pas IFormatable et n'ont pas d' ToString(string format) méthode.

Donc il jeter.

Maintenant, considérant:

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

L' ?. est un sucre syntaxique pour:

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

Ici, dt.Value est DateTime de la sorcière est - IFormatable et ont un ToString(string format) méthode.

Enfin la bonne façon d'écrire le premier code en C# 5.0 est:

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X