2016-01-12 9 views
5

Ich bin ziemlich neu in C# dynamic Stichwort. In einem meiner Projekte habe ich versucht, damit zu spielen und bin auf unerwartetes Verhalten gestoßen. Ich schaffte es, die Situation mit dem folgenden Code zu reproduzieren:Dynamic respektiert nicht Rückgabetyp

class Program 
{ 
    static DateTime? DateOnly(DateTime? time) 
    { 
     return time.HasValue ? (System.DateTime?)time.Value.Date : null; 
    } 

    static void Main(string[] args) 
    { 
     dynamic now = System.DateTime.Now; 
     var date = DateOnly(now); 
     Console.WriteLine(date.Value); // error thrown here 
     Console.Read(); 
    } 
} 

ich RuntimeBinderException

'System.DateTime' sagen erhalten enthält keine Definition für 'Wert'.

So wird die Variable date als DateTime statt DateTime? behandelt.

Es scheint dynamic irgendwie ignoriert die Rückgabetyp-Deklaration. Sollte ich vermeiden, var mit dynamic zu verwenden?

Antwort

5

Da Sie eine dynamic Variable an die DateOnly-Methode übergeben, wird auch der Rückgabetyp dynamisch. In diesem Fall ist Ihr var date eigentlich dynamic date. Es enthält eine boxed NULL-fähige DateTime, aber Boxen behält nicht die "Nullable" Teil, so in der Tat ist es nur eine Box DateTime, die keine Value Eigenschaft hat. Sie sollten also einfach Console.WriteLine(date) drucken, um den Wert zu drucken.

Wie Sie sehen können, Nullable Types und dynamic nicht sehr gut miteinander spielen ...

0

Sehen Sie sich Ihren Funktionsparameter an, Sie fragen nach einem NULL-fähigen Typ. DateTime (System.DateTime.Now) ist ein Werttyp und Werttypen sind standardmäßig nicht nullbar.

+0

@PoweredByOrange Nullable ist eine Struktur. –

2

Es gibt zwei Probleme. Eine davon ist, dass date immer noch dynamisch ist, weil die rechte Seite ein dynamischer Ausdruck ist. Wenn Sie date mit dem spezifischen Typ DateTime? deklariert hätten, würden Sie dies nicht sehen. Das andere Problem besteht darin, dass Sie einen Nullwerttyp zurückgeben und die Konvertierung in Dynamic als Boxing betrachtet wird. Nullable-Werttypen werden niemals als solche eingerahmt. Der zugrunde liegende Wertetyp wird ausgepackt, sodass sich date eher wie eine Referenz des Typs object verhält, die entweder eine DateTime haben kann oder null sein kann, keine Referenz auf eine DateTime?. Die Sammelmappe versucht dann, die Eigenschaft Value für DateTime aufzulösen und schlägt fehl. Wenn Sie Console.WriteLine(date) versuchen, wird es jedoch als mehrdeutig fehlschlagen, da diese Methode so viele Überladungen aufweist. So müssen Sie etwas tun wie Console.WriteLine((object)date), an diesem Punkt können Sie auch als object für dieses einfache Beispiel erklären.

+0

Meinten Sie "rechte Seite"? –

+0

@ThomasLevesque ja, ich meinte die andere links. Fest. –

Verwandte Themen