为什么跟踪引用不给引用的对象赋值?
Why tracking reference does not assign a value to the referenced object?
我不明白为什么当传递的变量在堆上时跟踪引用没有完成它的工作。这是代码:
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 ()
returns "1/4/2016 1:25:00 PM"
虽然第二个甚至 returns true
它没有将正确的值设置为 dc->Time
:调用 dc->Time.ToString ()
returns "1/1/0001 12:00:00 AM"
我在这里没有看到什么?
传递跟踪引用(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?。
我不明白为什么当传递的变量在堆上时跟踪引用没有完成它的工作。这是代码:
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 ()
returns "1/4/2016 1:25:00 PM"
虽然第二个甚至 returns true
它没有将正确的值设置为 dc->Time
:调用 dc->Time.ToString ()
returns "1/1/0001 12:00:00 AM"
我在这里没有看到什么?
传递跟踪引用(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?。