c#中创建事件和匿名方法的区别
Difference between creating an event and anonymous method in c#
在我的 c# winform 中,我正在使用 Timer。
Timer timer = new Timer();
对于Timer的tick事件,我们可以选择两种方式。
1. timer.Tick += new EventHandler(timer_Tick); //event
2. timer.Tick += delegate {/*to perform my operations on tick*/}; //anonymous method
谁能告诉我这两者的区别?
第三种也可以是:
timer.Tick += Timer_Tick;
会有什么不同吗?
您的示例中的主要区别在于将要执行的方法的结构。第一种情况:
- timer.Tick += new EventHandler(timer_Tick); //event
方法 timer_Tick
看起来像这样:
public void timer_Tick(object sender, EventArgs e)
{
}
因此您可以使用参数 object sender
和 EventArgs e
。您实际上在这里做的是调用 EventHandler
的构造函数,并将 delegate/pointer 传递给其中的方法。
虽然这个结构是由 Tick
属性 在你的第二种情况下给出的:
- timer.Tick += delegate {/to perform my operations on tick/}; //anonymous method
你创建了一个匿名方法,实际上用 delegate 关键字隐藏了参数,你无权访问它们。此外,您将无法从其他地方调用此方法。您无法模拟事件的触发,也无法重复使用代码。
在这里您可以使用 lambda 表达式来实际指定参数,以便您可以访问它们:
timer.Tick += (s, e) => { };
第三种情况:
timer.Tick += Timer_Tick;
是第一种情况的简化版。这里 Visual Studio 将在不指定事件类型的情况下为您推断出正确的方法结构。如果您实现的方法 Timer_Tick
与 Tick
要求的结构不匹配,编译器会报错!
示例:
委托 Tick
的类型为 EventHandler。这个类型指定了我在上面第一个案例中写的结构,你会在文档中看到它。如果(如图所示)委托 Tick
的结构与 Timer_Tick
方法的结构不匹配,则会出现错误。请注意,在此表达式中:
timer.Tick += Timer_Tick;
Timer_Tick
只是一个 delegate/a 指向必须实现的相关方法的指针!
有关代表和活动之间的根本区别,请查看 this article and this acticle
好吧,一个区别是可重用性。也就是说,如果您选择使用处理程序方法 timer_Tick
,那么您可以重复使用相同的处理程序方法来处理其他类似事件,如果您使用的是匿名方法或 lambda 表达式,则不能。
无法取消订阅(删除)匿名方法。因此,对事件使用匿名方法是非常糟糕的。这可能会导致内存泄漏!
在我的 c# winform 中,我正在使用 Timer。
Timer timer = new Timer();
对于Timer的tick事件,我们可以选择两种方式。
1. timer.Tick += new EventHandler(timer_Tick); //event
2. timer.Tick += delegate {/*to perform my operations on tick*/}; //anonymous method
谁能告诉我这两者的区别?
第三种也可以是:
timer.Tick += Timer_Tick;
会有什么不同吗?
您的示例中的主要区别在于将要执行的方法的结构。第一种情况:
- timer.Tick += new EventHandler(timer_Tick); //event
方法 timer_Tick
看起来像这样:
public void timer_Tick(object sender, EventArgs e)
{
}
因此您可以使用参数 object sender
和 EventArgs e
。您实际上在这里做的是调用 EventHandler
的构造函数,并将 delegate/pointer 传递给其中的方法。
虽然这个结构是由 Tick
属性 在你的第二种情况下给出的:
- timer.Tick += delegate {/to perform my operations on tick/}; //anonymous method
你创建了一个匿名方法,实际上用 delegate 关键字隐藏了参数,你无权访问它们。此外,您将无法从其他地方调用此方法。您无法模拟事件的触发,也无法重复使用代码。
在这里您可以使用 lambda 表达式来实际指定参数,以便您可以访问它们:
timer.Tick += (s, e) => { };
第三种情况:
timer.Tick += Timer_Tick;
是第一种情况的简化版。这里 Visual Studio 将在不指定事件类型的情况下为您推断出正确的方法结构。如果您实现的方法 Timer_Tick
与 Tick
要求的结构不匹配,编译器会报错!
示例:
委托 Tick
的类型为 EventHandler。这个类型指定了我在上面第一个案例中写的结构,你会在文档中看到它。如果(如图所示)委托 Tick
的结构与 Timer_Tick
方法的结构不匹配,则会出现错误。请注意,在此表达式中:
timer.Tick += Timer_Tick;
Timer_Tick
只是一个 delegate/a 指向必须实现的相关方法的指针!
有关代表和活动之间的根本区别,请查看 this article and this acticle
好吧,一个区别是可重用性。也就是说,如果您选择使用处理程序方法 timer_Tick
,那么您可以重复使用相同的处理程序方法来处理其他类似事件,如果您使用的是匿名方法或 lambda 表达式,则不能。
无法取消订阅(删除)匿名方法。因此,对事件使用匿名方法是非常糟糕的。这可能会导致内存泄漏!