2016-01-04 56 views
0

我不明白爲什麼當傳遞變量在堆上時跟蹤引用沒有完成它的工作。下面是代碼:爲什麼跟蹤引用不會爲引用的對象分配值?

ref class DataContainer 
    { 
    public: 
     property DateTime Time; 
    }; 

DataContainer^ dc = gcnew DataContainer(); 
DateTime timeOnStack; 
// first call with output variable on the stack 
bool timeParsed = DateTime::TryParseExact ("20160104132500184", "yyyyMMddHHmmssfff", CultureInfo::InvariantCulture, DateTimeStyles::None, timeOnStack); 
// second call with output variable on the heap 
timeParsed = DateTime::TryParseExact ("20160104132500184", "yyyyMMddHHmmssfff", CultureInfo::InvariantCulture, DateTimeStyles::None, (dc->Time)); 

首先TryParseExact調用,它使用本地初始化的變量timeOnStack把解析的DateTime值按預期工作,並設置正確分析日期:致電timeOnStack.ToString()回報"1/4/2016 1:25:00 PM" 而第二個甚至返回true它不設置正確的值爲dc->Time:致電dc->Time.ToString()返回"1/1/0001 12:00:00 AM"

我在這裏沒有看到什麼?

回答

3

傳遞一個跟蹤引用(在C#中爲ref)傳遞一個對象的本地存儲的地址,而不是傳遞該對象。但是,在您的示例中,dc->Time不是局部變量或字段,而是屬性。請記住,在引擎蓋下,屬性是getter/setter方法對。你在這裏有相當於dc->GetTime()

編譯器正在進行方法調用,並將該方法調用的結果作爲跟蹤參考。該物業沒有分配給該物業;這不是它的工作原理。接收方法調用結果並作爲跟蹤參考傳遞的臨時局部變量不可用。

如果你在C#中嘗試這樣做,你會得到一個錯誤A property or indexer may not be passed as an out or ref parameter. C++/CLI允許它通過,雖然可能不是你想要的。

編譯器可以選擇實現一些語法糖:調用屬性getter,賦值給臨時變量,然後調用setter。但是,C#和C++/CLI都選擇不實現它,原因很充分:請參閱why C# does not provide internal helper for passing property as reference?

相關問題