为什么活动需要代表?为什么我们甚至需要事件
本文关键字:为什么 事件 我们 活动 | 更新日期: 2023-09-27 18:35:38
在过去的几周里,我一直对事件感到困惑。我了解代表们的工作方式,而不是详细的工作方式,但足以知道 delegate datatype
是单个演员代表。 delegate void
是一个多播委托 - 对方法的引用列表。
我知道委托类型编译为类,但不幸的是,我仍然不确定该方法是如何引用的。例如
delegate void TestDelegate();
TestDelegate testDelegate = new TestDelegate(myObject.SomeMethod) ;
问题 1:我认为 myObject 是目标,SomeMethod 是要引用的方法,但我只传递一个输入。那么myObject.SomeMethod是否编译成一个字符串,字符串是否按句点分割?我知道很荒谬。
问题2:添加到多播委托时
multicastdelegate+=newmethodtobereference
multicastdelegate() ;
调用列表中的每个方法都被调用或通知?如果这是真的,为什么我需要事件或event
关键字?只是为了告诉开发人员,嘿,这是一个事件吗?因为我非常困惑,所以我只想在这个阶段继续前进,哈哈。这是我今天编写的示例代码,用于测试它,无论我是否需要事件关键字。
using System;
namespace LambdasETs
{
public delegate void IsEvenNumberEventHandler(int numberThatIsEven);
public class IsEvenNumberFound
{
public IsEvenNumberEventHandler IsEvenNumberEvent;
private int number;
public void InputNumber(int n)
{
if(number %2 ==0)
{
if (IsEvenNumberEvent != null)
{
IsEvenNumberEvent(n);
}
}
}
public static void Main()
{
IsEvenNumberFound isEvenNumberFound = new IsEvenNumberFound();
isEvenNumberFound.IsEvenNumberEvent += IsEvenNumberAction;
isEvenNumberFound.InputNumber(10);
Console.ReadLine();
}
public static void IsEvenNumberAction(int number)
{
Console.WriteLine("{0} is an even number!", number);
}
}
}
将事件关键字添加到字段public IsEvenNumberEventHandler IsEvenNumberEvent;
没有区别。请解释一下,以便菜鸟可以理解谢谢。
事件是委托的访问器,就像属性是字段的访问器一样。 具有大致相同的目标,它可以防止其他代码弄乱委托对象。 就像当你不知道的一堆代码订阅了回调时将其设置为 null。 事件将访问限制为仅使用 += 和 -= 运算符添加和删除事件处理程序,外部代码根本无法访问专用委托对象。
并使用添加和删除访问器自定义订阅。 您通常不会这样做,因为您通常对编译器生成的默认访问器感到满意。 包括存储委托的隐藏支持字段。 但是,例如,在框架代码中并不少见。 与 System.Windows.Forms.Control 支持的许多事件的所有事件处理程序一样,它们都存储在单个 EventHandlerList 中。 或 WPF 等效项 EventHandlersStore。
但足以知道委托数据类型是单个强制转换委托。 委托 void 是一个多播委托 - 对方法的引用列表。
不对。所有"正常"委托都是多播的,即使它们具有非 void 返回类型。
问题 1:我认为 myObject 是目标,SomeMethod 是要引用的方法,但我只传递一个输入。那么myObject.SomeMethod是否编译成一个字符串,字符串是否按句点分割?我知道很荒谬。
否,myObject.SomeMethod
是一个方法组。这种委托实例创建方式涉及一些编译器魔术。
多播委托+=新方法引用
如果multicastdelegate
是一个普通的委托变量,这等效于multicastdelegate = multicastdelegate + newmethodtobereference
即它创建一个调用多个方法的新委托,并将其分配给multicastdelegate
。
现在回答你的主要问题:活动的目的是什么?
事件具有委托类型。它们的行为类似于属性。它们的目的是封装,特别是它们只允许消费者订阅(+=
)和取消订阅(-=
),但不允许读取事件的值。
属性是两种方法的组合:get
和set
。
事件是两种公共方法的组合subscribe
和unsubscribe
,在类似字段的事件的情况下,也类似于私有获取者。