2016-01-12 35 views
5

我對C#相當陌生#dynamic關鍵字。在我的其中一個項目中,我嘗試使用它,並遇到一些意外的行爲。我設法再現與下面的代碼的情況:動態不尊重退貨類型

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(); 
    } 
} 

我得到一個RuntimeBinderException

「System.DateTime的」不包含「價值」的定義。

所以可變date被視爲DateTime代替DateTime?

它看起來像dynamic某種程度上忽略返回類型聲明。 我是否應該避免在dynamic處使用var

回答

5

因爲你傳遞一個dynamic變量到DateOnly方法,返回類型也變得動態的。所以在這種情況下,您的var date實際上是dynamic date。它包含一個可空盒裝DateTime,但拳擊不保留「可空」的一部分,所以實際上它只是一個盒裝DateTime,它不具有Value財產。所以你應該做Console.WriteLine(date)打印價值。

正如你所看到的,可空類型和dynamic不玩很好地結合在一起......

0

看看你的函數參數,你要求一個可爲空的類型。 DateTime(System.DateTime.Now)是一個值類型,默認情況下,值類型不可爲空。

+0

@PoweredByOrange可空是一個結構。 –

2

有兩個問題。一個是date仍然是動態的,因爲右側是一個動態表達式。如果您已經聲明date與特定類型DateTime?你不會看到這一點。另一個問題是,你正在返回一個可爲空的值類型,並且轉換爲動態被認爲是裝箱。可爲空的值類型從不像這樣裝箱。底層值類型已解包,因此date的行爲更像是類型爲object的參考,它可以具有DateTime或可以爲null,而不是對DateTime?的引用。綁定器然後嘗試根據DateTime解析屬性Value並失敗。如果您嘗試Console.WriteLine(date),但它會失敗,因爲該方法有很多重載。所以你必須做一些類似於Console.WriteLine((object)date)的事情,在這一點上,你可以聲明dateobject這個簡單的例子。

+0

您的意思是「右手邊」? –

+0

@ThomasLevesque是的,我的意思是另一個左邊。固定。 –