我不明白为什么当传递变量在堆上时跟踪引用没有完成它的工作。这是代码:
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"
我在这里看不到什么?
答案 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?。