.net 如何正确访问c++/CLI initonly TimeSpan字段?

.net 如何正确访问c++/CLI initonly TimeSpan字段?,.net,visual-c++,.net-4.0,c++-cli,.net,Visual C++,.net 4.0,C++ Cli,以下代码编译时出现警告和intellisense错误: ref class Test { initonly static TimeSpan Delay = TimeSpan(1,1,1); Test() { long long ticks = Delay.Ticks; // << problem } }; ref类测试{ initonly静态时间间隔延迟=时间间隔(1,1,1); 测试(){ long long ticks=Delay.t

以下代码编译时出现警告和intellisense错误:

ref class Test {
    initonly static TimeSpan Delay = TimeSpan(1,1,1); 

    Test() {
        long long ticks = Delay.Ticks; // << problem
    }
};
ref类测试{
initonly静态时间间隔延迟=时间间隔(1,1,1);
测试(){

long long ticks=Delay.ticks;//这是一个相当大的失败。警告是准确的,编译器对TimeSpan::Tick属性getter了解不够。它无法确保getter不会做任何可能改变结构值从而使initonly契约无效的事情。它通过创建一个副本来解决这个问题因为这可能是一个性能问题,所以会对该结构进行警告。这有点过重,其他托管编译器在复制时没有对其进行任何说明。我只是在它前面插入一个
#pragma警告(disable:4395)
,因此该警告被抑制

IntelliSense错误仅在我在VS2012中尝试此操作时出现。这是一个错误。您可以在connect.microsoft.com上报告它

考虑到这种痛苦,而且这似乎是一个私有类成员,我只想放弃init来获得成功。如果不希望这样做,那么您可以使用属性包装字段,有意创建副本,从而消除这两个问题,如下所示:

ref class Test {
    initonly static TimeSpan _delay = TimeSpan(1,1,1); 
    static property TimeSpan Delay { 
        TimeSpan get() { return _delay; }
    }

    Test() {
        long long ticks = Delay.Ticks;
    }
};

抖动优化器将消除它,因此不必担心开销。

感谢Hans Passant的解释,我现在更了解上下文

我刚刚遇到同样的问题

我的解决办法是

  • 将“initonly”替换为“const”
  • 访问时,只需丢弃常量,就不会留下任何错误/警告
也许这不是“最先进的”编码,但它工作得很好,请参见
(VisualStudio2017仍然暴露了此行为/问题)

此警告仍然存在于VS2015中。