委托和事件之间的区别是什么?两者不都持有可以执行的函数的引用吗?
当前回答
对于生活在2020年的人们来说,想要一个干净的答案……
定义:
Delegate:定义一个函数指针。 事件:定义 (1)受保护接口,以及 (2)操作(+=,-=),和 (3)优点:你不再需要使用new关键字。
关于形容词protected:
// eventTest.SomeoneSay = null; // Compile Error.
// eventTest.SomeoneSay = new Say(SayHello); // Compile Error.
还要注意来自微软的这一部分:https://learn.microsoft.com/en-us/dotnet/standard/events/#raising-multiple-events
代码示例:
委托:
public class DelegateTest
{
public delegate void Say(); // Define a pointer type "void <- ()" named "Say".
private Say say;
public DelegateTest() {
say = new Say(SayHello); // Setup the field, Say say, first.
say += new Say(SayGoodBye);
say.Invoke();
}
public void SayHello() { /* display "Hello World!" to your GUI. */ }
public void SayGoodBye() { /* display "Good bye!" to your GUI. */ }
}
事件:
public class EventTest
{
public delegate void Say();
public event Say SomeoneSay; // Use the type "Say" to define event, an
// auto-setup-everything-good field for you.
public EventTest() {
SomeoneSay += SayHello;
SomeoneSay += SayGoodBye;
SomeoneSay();
}
public void SayHello() { /* display "Hello World!" to your GUI. */ }
public void SayGoodBye() { /* display "Good bye!" to your GUI. */ }
}
参考:
事件和委托——解释c#中事件和委托模式之间的重要区别,以及它们为什么有用。: https://dzone.com/articles/event-vs-delegate
其他回答
Delegate是一个类型安全的函数指针。事件是使用委托的发布者-订阅者设计模式的实现。
您还可以在接口声明中使用事件,但委托则不是这样。
对于生活在2020年的人们来说,想要一个干净的答案……
定义:
Delegate:定义一个函数指针。 事件:定义 (1)受保护接口,以及 (2)操作(+=,-=),和 (3)优点:你不再需要使用new关键字。
关于形容词protected:
// eventTest.SomeoneSay = null; // Compile Error.
// eventTest.SomeoneSay = new Say(SayHello); // Compile Error.
还要注意来自微软的这一部分:https://learn.microsoft.com/en-us/dotnet/standard/events/#raising-multiple-events
代码示例:
委托:
public class DelegateTest
{
public delegate void Say(); // Define a pointer type "void <- ()" named "Say".
private Say say;
public DelegateTest() {
say = new Say(SayHello); // Setup the field, Say say, first.
say += new Say(SayGoodBye);
say.Invoke();
}
public void SayHello() { /* display "Hello World!" to your GUI. */ }
public void SayGoodBye() { /* display "Good bye!" to your GUI. */ }
}
事件:
public class EventTest
{
public delegate void Say();
public event Say SomeoneSay; // Use the type "Say" to define event, an
// auto-setup-everything-good field for you.
public EventTest() {
SomeoneSay += SayHello;
SomeoneSay += SayGoodBye;
SomeoneSay();
}
public void SayHello() { /* display "Hello World!" to your GUI. */ }
public void SayGoodBye() { /* display "Good bye!" to your GUI. */ }
}
参考:
事件和委托——解释c#中事件和委托模式之间的重要区别,以及它们为什么有用。: https://dzone.com/articles/event-vs-delegate
活动和代表之间的误解太大了!!委托指定TYPE(例如类或接口),而事件只是一种成员(例如字段、属性等)。并且,就像任何其他类型的成员一样,事件也有类型。然而,在事件的情况下,事件的类型必须由委托指定。例如,不能声明由接口定义的类型的事件。
最后,我们可以做以下观察:事件的类型必须由委托定义。这是事件和委托之间的主要关系,在第二节中描述。18定义ECMA-335 (CLI)分区I到VI的事件:
在典型用法中,TypeSpec(如果存在)标识一个签名与传递给事件的fire方法的参数匹配的委托。
However, this fact does NOT imply that an event uses a backing delegate field. In truth, an event may use a backing field of any different data structure type of your choice. If you implement an event explicitly in C#, you are free to choose the way you store the event handlers (note that event handlers are instances of the type of the event, which in turn is mandatorily a delegate type---from the previous Observation). But, you can store those event handlers (which are delegate instances) in a data structure such as a List or a Dictionary or any other else, or even in a backing delegate field. But don’t forget that it is NOT mandatory that you use a delegate field.
An event in .net is a designated combination of an Add method and a Remove method, both of which expect some particular type of delegate. Both C# and vb.net can auto-generate code for the add and remove methods which will define a delegate to hold the event subscriptions, and add/remove the passed in delegagte to/from that subscription delegate. VB.net will also auto-generate code (with the RaiseEvent statement) to invoke the subscription list if and only if it is non-empty; for some reason, C# doesn't generate the latter.
Note that while it is common to manage event subscriptions using a multicast delegate, that is not the only means of doing so. From a public perspective, a would-be event subscriber needs to know how to let an object know it wants to receive events, but it does not need to know what mechanism the publisher will use to raise the events. Note also that while whoever defined the event data structure in .net apparently thought there should be a public means of raising them, neither C# nor vb.net makes use of that feature.
推荐文章
- Linq选择列表中存在的对象(A,B,C)
- c# .NET中的App.config是什么?如何使用它?
- c#:如何获得一个字符串的第一个字符?
- String类中的什么方法只返回前N个字符?
- 更好的方法将对象转换为int类型
- 我可以将c#字符串值转换为转义字符串文字吗?
- 在c#中转换char到int
- c#中朋友的对等物是什么?
- 关键字使用virtual+override vs. new
- 在ASP中选择Tag Helper。NET Core MVC
- 如何在没有任何错误或警告的情况下找到构建失败的原因
- 跨线程操作无效:控件“textBox1”从创建它的线程以外的线程访问
- 否ConcurrentList<T>在。net 4.0?
- 在c#中解析字符串为日期时间
- 如何检测“搜索”HTML5输入的清除?