12

廃止されたイベントが使用されているときにVisualStudioC#コンパイラにビルド警告を発行させるためのトリックまたは回避策を知っている人はいますか?

パブリックイベントを使用して単純なアセンブリを作成し、そのイベントにObsolete属性を適用すると、そのアセンブリを参照して別のプロジェクトでイベントをサブスクライブすると、ビルド時にコンパイラーが警告を発行しません(警告レベルが最も高い場合でも)または警告がエラーに設定されます)。

プロジェクト1でのイベントの宣言:

    public class APIClass
    {
        [Obsolete("Obsolete in v2.0")]
        public event EventHandler ObsoleteEvent;
    }

プロジェクト2で廃止されたイベントを使用しても、ビルド警告は発生しません。

    private void SubscribeToEvent(APIClass apiClass)
    {
        apiClass.ObsoleteEvent += delegate { };
    }

ソースファイルを開くと、Visual Studioはイベントを廃止として認識し、警告(またはエラー)をエラーリストに追加します。 バックグラウンドソース処理は警告を認識します

ただし、ビルドするとすぐに警告が消え、ビルド出力に表示されません。 コンパイル後に警告が消えました

欠落しているコンパイラ警告はバグとして提出されたようですが、修正されるまで、誰かがイベントを使用したときに警告を強制する方法はありますか?そうしないと、外部の消費者に発信コードを変更する必要があることを警告する方法がありません。

4

1 に答える 1

4

これは認められたバグのようですが、あなたの状況でうまくいくことを願っている回避策を思いつくことができます。

event キーワードは、特定の署名に準拠するマルチキャスト デリゲートのシンタックス ショートカットにすぎず、同様の方法でプロパティに適切に公開されます。あなたが試すことができる1つの解決策は、イベントを非公開にし、リスナーを追加するためのメソッドを公開することです。これを廃止済みとしてマークします。

public class APIClass
{
    [Obsolete("Obsolete in v2.0")]
    private event EventHandler ObsoleteEvent;

    [Obsolete("Obsolete in v2.0")]
    public void AddListener(EventHandler eh)
    {
        ObsoleteEvent += eh;
    }

}

private static void SubscribeToEvent(APIClass apiClass)
{
    //apiClass.ObsoleteEvent += delegate { };
    apiClass.AddListener(delegate { });
}

この回避策がうまくいくことを願っています!頑張ってください!

* 編集 *

これがバグである理由をさらに説明するために、このコードによって生成された MSIL を示します。プロパティ キーワードのように動作するイベント キーワードの類推に従って、「add_ObsoleteEvent」および「remove_ObsoleteEvent」メソッドを発行します。それらはエディターには表示されませんが、コードがどのようにリンクされているかを示しています。

これは、作成された add メソッドです。'Obsolete' 属性がコンパイラで生成されたメソッドに追加されていないことに注意してください。

.method private hidebysig specialname instance void 
        add_ObsoleteEvent(class [mscorlib]System.EventHandler 'value') cil managed
{
  // Code size       48 (0x30)
  .maxstack  3

/// rest omitted

これは、'Obsolete' 属性を手動で追加した、作成した "AddListener" メソッドとは対照的です。コンパイラがメソッドに 'Obsolete' 属性を追加したことに注意してください。

.method public hidebysig instance void  AddListener(class [mscorlib]System.EventHandler eh) cil     managed
{
  .custom instance void [mscorlib]System.ObsoleteAttribute::.ctor(string) = ( 01 00 10 4F 62 73     6F 6C 65 74 65 20 69 6E 20 76   // ...Obsolete in v
                                                                              32 2E 30 00 00 )                                      // 2.0..
  // Code size       10 (0xa)
  .maxstack  8

/// rest omitted.

これをコンパイル時にエディターから離れた場所で警告を発行するには、これを MSIL に手動で追加することができる場合があります。私はこれを試していないので、うまくいくかどうかはわかりません。しかし、問題が発生している理由を示すために、この編集を行うと思いました。それが役立つことを願っています!

于 2012-12-05T17:23:47.120 に答える