10

次のコードは、警告と IntelliSense エラーでコンパイルされます。

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 フィールドのアドレスを取得することは許可されていません

ティックに正しくアクセスするには?

4

2 に答える 2

13

まあ、それはかなり大きな失敗クジラです。警告は正確です。コンパイラはTimeSpan::Tickプロパティゲッターについて十分に認識していません。構造体の値を変更してinitonlyコントラクトを無効にする可能性のあることをゲッターが実行しないことを保証することはできません。これは構造体のコピーを作成することで解決し、これはパフォーマンスの問題である可能性があるため、警告します。それは少し手間がかかります、他のマネージドコンパイラはそれについて何も言わずにコピーを作成します。#pragma warning(disable:4395)警告が抑制されるように、その前に突っ込みます。

IntelliSenseエラーは、VS2012でこれを試した場合にのみ表示されます。それはバグです。connect.microsoft.comで報告できます。

悲惨さとこれがプライベートクラスのメンバーのように見えることを考えると、私は先に進むために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;
    }
};

ジッタオプティマイザはそれを取り除くので、オーバーヘッドについて心配する必要はありません。

于 2012-12-12T03:01:47.200 に答える