为什么跟踪引用不会为引用的对象赋值?

时间:2016-01-04 14:57:17

标签: .net c++-cli tracking-reference

我不明白为什么当传递变量在堆上时跟踪引用没有完成它的工作。这是代码:

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值按预期工作并正确设置解析日期:call timeOnStack.ToString ()返回"1/4/2016 1:25:00 PM" 虽然第二个甚至返回true,但它没有为dc->Time设置正确的值:call dc->Time.ToString ()返回"1/1/0001 12:00:00 AM"

我在这里看不到什么?

1 个答案:

答案 0 :(得分:3)

在C#中传递跟踪引用(require 'yaml' def stringify_values(obj) temp = {} obj.each do |k, v| if v.is_a?(Hash) temp[k] = stringify_values(v) else temp[k] = v.to_s end end temp end hash = { post: { id: 123, text: 'foobar', } } puts stringify_values(hash).to_yaml #=> --- :post: :id: '123' :text: foobar )是传递对象的本地存储的地址,而不是传递对象。但是,示例中的ref不是局部变量或字段,而是属性。请记住,在引擎盖下,属性是getter / setter方法对。你在这里所拥有的是dc->Time

编译器正在进行方法调用,并将该方法调用的结果作为跟踪引用传递。没有任何转让回酒店;这不是它的工作原理。接收到方法调用结果并作为跟踪引用传递的临时局部变量不可用。

如果您在C#中尝试此操作,您将收到错误dc->GetTime() C ++ / CLI允许此操作,但可能不是您想要的。

编译器可以选择实现一些语法糖:调用属性getter,赋值给临时变量,然后调用setter。但是,C#和C ++ / CLI都选择不实现它,原因很简单:请参阅why C# does not provide internal helper for passing property as reference?