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

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

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

问题是:
  • 警告C4395:'System::TimeSpan::Ticks::get':成员函数将
    在initonly数据成员'Test::Delay'
  • 的副本上调用
  • IntelliSense:不允许使用initonly字段的地址

  • 如何正确访问Ticks?

    最佳答案

    好吧,那是相当主要的失败目标。该警告是准确的,编译器对TimeSpan::Tick属性getter的了解不足。它不能确保getter不会做任何可能改变struct的值的操作,从而使initonly契约(Contract)无效。它通过复制该结构来解决该问题并对其进行警告,因为这可能是性能问题。这有点笨拙,其他托管编译器会在不说明任何内容的情况下进行复制。我只是在它前面加了一个#pragma warning(disable:4395),所以警告被抑制了。

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

    考虑到苦难,而且这似乎是私有(private)类(class)的成员,我只是放弃initonly以取得成功。如果不希望这样,则可以使用属性包装字段,有意地创建副本,从而消除这两个问题,例如:

    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;
        }
    };
    

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

    关于.net - 如何正确访问c++/CLI initonly TimeSpan字段?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13831773/

    10-11 13:02