作为C#编程世界中的所有其他内容,事件概念也遵循特定的规则并具有自己的语法。措辞如下:
- 定义为EventHandler的事件实际上只是一种特殊方法(委托)签名的快捷方式-
public delegate void EventHandler(object sender, EventArgs e)
[1]。在C#中,每当您有一个签名时,您总是知道需要在右侧或作为参数中编写什么,以连接/调用某些对象/方法等。
- 事件定义后,需要订阅以便在发生事件时获得通知。订阅事件的语法为+=。自然而然地,取消订阅事件的语法为-=。MSDN表示语法应为
object.event += eventHandler
(或object.event += new EventHandler(eventHandler);
)
- 因此,在事件被定义之后(
event Event SomeEvent;
),所有剩下的就是创建一个可以绑定到此事件的方法。该方法必须具有与EventHandler相同的签名,因此它应该与[1]的签名匹配,并且可以是private void numberChangedEventHandler(object sender, EventArgs eventArguments)
现在您知道需要在+=右侧编写什么内容了。
例如:
public class NumberSequence
{
private readonly List<int> numbers = new List<int>();
private readonly Random random = new Random();
public event EventHandler DifferentNumbersEvent;
public NumberSequence()
{
Enumerable.Range(1, 100).ToList().ForEach(number =>
{
numbers.Add(random.Next(1, 100));
});
}
public List<int> Numbers { get { return numbers; } }
public void TraverseList()
{
for (var i = 1; i < this.numbers.Count; i++)
{
if (this.numbers[i - 1] != this.numbers[i])
{
if (this.DifferentNumbersEvent != null)
{
this.DifferentNumbersEvent(this, EventArgs.Empty);
}
}
}
}
}
在使用类之前,定义事件处理程序,它将会“监听”并在事件被“触发”时被调用(再次强调措辞):
private void differentNumberEventHandler(Object sender, EventArgs eventArguments)
{
Console.WriteLine("Different numbers...");
}
而且用法:
var ns = new NumberSequence();
ns.DifferentNumbersEvent += differentNumberEventHandler;
ns.TraverseList();
除了这种符号表示法(lambda / 匿名方法 / ...)外,其他都只是语法糖,例如:
object.Event += (s, e) => { // code ... };
与 object.Event += (Object sender, EventArgs eventArguments) => { // code ... };
是相同的。你认识这个签名吗?它与 private void differentNumberEventHandler...
相同。
通常我们需要通过事件传递信息,在这种情况下,也许我们想要看到这两个数字。C# 允许您使用自定义事件参数轻松地实现此目的。只需创建一个继承 EventArgs
类的类,并添加应该传递的数据的属性,即这种情况下的数字:
public class NumbersInfoEventArgs : EventArgs
{
public int Number1 { get; set; }
public int Number2 { get; set; }
}
然后在声明事件时指定它将传递类型为NumbersInfoEventArgs
的数据(再次签名):
public event EventHandler<NumbersInfoEventArgs> DifferentNumbersEvent;
...
this.DifferentNumbersEvent(this, new NumbersInfoEventArgs
{
Number1 = this.numbers[i - 1],
Number2 = this.numbers[i]
});
最后但并非不重要的是,事件处理函数的签名
应该与事件的签名匹配:
private void differentNumberEventHandler(Object sender, NumbersInfoEventArgs eventArguments)
{
Console.WriteLine("Different numbers {0} - {1}", eventArguments.Number1, eventArguments.Number2);
}
And voila, the output is:
Different numbers 89 - 86
Different numbers 86 - 53
Different numbers 53 - 12
Different numbers 12 - 69