1

我已经开始阅读 Visual Studio 附带的 C# 语言规范: C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC#\Specifications\1033

在章节1.6.7.4 Events中,我发现了以下内容:

事件是使类或对象能够提供通知的成员。一个事件被声明为一个字段,除了声明包含一个事件关键字并且类型必须是委托类型。

在声明事件成员的类中,事件的行为就像委托类型的字段(前提是事件不是抽象的并且不声明访问器)。该字段存储对代表已添加到事件的事件处理程序的委托的引用。如果不存在事件句柄,则该字段为空。

该类 List<T>声明了一个名为 Changed 的​​事件成员,它表示已将新项目添加到列表中。Changed 事件由 OnChanged 虚拟方法引发,该方法首先检查事件是否为空(意味着不存在处理程序)。引发事件的概念完全等同于调用由事件表示的委托——因此,引发事件没有特殊的语言结构。

客户端通过事件处理程序对事件做出反应。事件处理程序使用 += 运算符附加并使用 -= 运算符删除。下面的示例将一个事件处理程序附加到 的 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"
  }
}

对于需要控制事件的底层存储的高级场景,事件声明可以显式地提供添加和删除访问器,这有点类似于属性的设置访问器。

当我发现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>在规范的前面定义,在标题为“其他函数成员”的部分中:

下表显示了一个名为 List 的通用类,它实现了一个可增长的对象列表。

该类List<T>与该类没有关系System.Collections.Generic.List<T>,只是它们具有相同的名称。

于 2013-06-20T19:00:52.583 回答
1

你没有错过任何东西,System.Collections.Generic.List<T>没有任何Changed事件。

我认为这只是一个示例,而不是说明List<T>类应该是什么样子的规范。(这没有多大意义,C# 规范只指定了库的一小部分,当然没有指定任何特定的集合类。)

另请注意,规范讨论的是一些通用List<T>类,而不是特定System.Collections.Generic.List<T>类。

于 2013-06-20T18:51:29.630 回答