2010-12-02 9 views
0

シールされたC++/CLIクラスでパブリックイベントを宣言すると、コード解析の警告CA1047が表示されます。この警告は、自動生成された保護されたメンバー関数から来ているようです。この警告を修正するにはどうすればよいですか?CA1047「メンバーをプライベート、パブリック、または内部のメンバーにする」とC++/CLIのイベント

例を示します。このコード

ref class Test sealed { 
public: 
    event EventHandler^ blah; 
}; 

が発生:

警告:CA1047:Microsoft.Design:メンバー作る 'テスト::何とか::昇給(オブジェクト^、のEventArgs ^)'、プライベート、パブリック、または内部

+0

最小限の例を表示できますか? –

答えて

1

私はこの質問をよりよく文書化します。このコード

ref class Test sealed { 
public: 
    event EventHandler^ blah; 
}; 

が発生:

警告:CA1047:Microsoft.Design:メンバー作る 'テスト::何とか::昇給(オブジェクト^、のEventArgs ^)'、プライベート、パブリック、または内部

はい、イベントアクセサーを自分で指定しないと、コンパイラーによって生成されます。 add、remove、raiseアクセサーを自動生成します。あなたはIldasm.exeをして見たときに後者の方が次のようになります。

.method family hidebysig specialname instance void 
     raise_blah(object value0, 
        class [mscorlib]System.EventArgs value1) cil managed 
{ 
    // etc.. 
} 

家族属性は、コード分析の警告を引き起こすものです。自動生成された追加および削除アクセサは、もちろん公開されています。それらを自分で書くことは疑わしい回避策です。カスタムアクセサを実装する本当の理由がある場合は、これを実行するだけです。ボイラープレートのバージョンは次のようになります。

using namespace System::Runtime::CompilerServices; 

ref class Test sealed { 
private: 
    EventHandler^ foo; 
public: 
    event EventHandler^ blah { 
     [MethodImpl(MethodImplOptions::Synchronized)] 
     void add(EventHandler^ d) { foo += d; } 
     [MethodImpl(MethodImplOptions::Synchronized)] 
     void remove(EventHandler^ d) { foo -= d; } 
    private: 
     void raise(Object^ sender, EventArgs^ e) { 
      EventHandler^ handler = foo; 
      if (handler != nullptr) handler(sender, e); 
     }; 
    } 
}; 

これは確かに警告を抑制します。プロペラを回転させない場合は、[SuppressMessage]属性を使用することをお勧めします。

+0

ここで 'raise'アクセサは実際に必要ですか?結局のところ、バッキングプロパティを直接使用することも、単純なヘルパー関数を使用して(競合条件回避ロジックを提供する)こともできます。あるいは、明示的に何も指定されておらず、FxCopをトリガーしている場合、コンパイラは自動的に 'raise'メソッドを生成しますか? –

+0

はい、2番目の部分です。 –

+0

自動コードの生成が、適切なアクセサーをraiseに設定するほどスマートではないことには、あまりにも悪いです。 – Eric

関連する問題