1

Visual Studio に付属している C# 言語仕様を読み始めました。 C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC#\Specifications\1033

1.6.7.4 Eventsでは、次のことがわかりました。

イベントは、クラスまたはオブジェクトが通知を提供できるようにするメンバーです。イベントは、宣言に event キーワードが含まれていることと、型がデリゲート型である必要があることを除いて、フィールドと同様に宣言されます。

イベント メンバーを宣言するクラス内では、イベントはデリゲート型のフィールドのように動作します (イベントが抽象ではなく、アクセサーを宣言しない場合)。このフィールドには、イベントに追加されたイベント ハンドラーを表すデリゲートへの参照が格納されます。イベント ハンドルが存在しない場合、フィールドは null です。

この List<T>クラスは、Changed という単一のイベント メンバーを宣言します。これは、新しい項目がリストに追加されたことを示します。Changed イベントは、OnChanged 仮想メソッドによって発生します。このメソッドは、最初にイベントが null (つまり、ハンドラーが存在しないことを意味します) かどうかをチェックします。イベントを発生させるという概念は、イベントによって表されるデリゲートを呼び出すこととまったく同じです。したがって、イベントを発生させるための特別な言語構造はありません。

クライアントは、イベント ハンドラを通じてイベントに反応します。イベント ハンドラーは、+= 演算子を使用して追加され、-= 演算子を使用して削除されます。次の例では、イベント ハンドラーを の Changed イベントにアタッチしList<string>ます。

using System;
class Test
{
  static int changeCount;
  static void ListChanged(object sender, EventArgs e) {
      changeCount++;
  }
  static void Main() {
      List<string> names = new List<string>();
      names.Changed += new EventHandler(ListChanged);
      names.Add("Liz");
      names.Add("Martha");
      names.Add("Beth");
      Console.WriteLine(changeCount);     // Outputs "3"
  }
}

イベントの基になるストレージの制御が必要な高度なシナリオでは、イベント宣言で add アクセサーと remove アクセサーを明示的に指定できます。これは、プロパティの set アクセサーに多少似ています。

イベントを知ったときはかなり驚いたList.Changedので、Visual Studio 2012 で新しいコンソール アプリケーションを作成し、ターゲット フレームワークを .NET 4.5 に設定しました。

(Visual Studio と開発者コマンド プロンプトの両方を使用して) アプリケーションをコンパイルしようとすると、次のエラーが発生しました。

エラー CS1061: 'System.Collections.Generic.List' には 'Changed' の定義が含まれておらず、タイプ 'System.Collections.Generic.List' の最初の引数を受け入れる拡張メソッド 'Changed' が見つかりませんでした (不足していますか? using ディレクティブまたはアセンブリ参照?)

ここで何か不足していますか?ILSpy を使用してクラス定義を確認しましたが、イベントが表示されませんChanged

4

2 に答える 2

2

このクラスList<T>は、仕様の前半のOther function membersというタイトルのセクションで定義されています。

次の表は、拡張可能なオブジェクトのリストを実装する List というジェネリック クラスを示しています。

このクラスは、同じ名前を持っていることを除いてList<T>、クラスとは何の関係もありません。System.Collections.Generic.List<T>

于 2013-06-20T19:00:52.583 に答える