我已经阅读了很多关于代表和事件的材料和示例,但我真的很难理解C#中的事件。我理解委托是有效的方法指针,你可以在调用委托时添加方法然后一起执行,假设它符合输入参数和委托的返回类型。
(我非常清楚事件是在堆栈溢出时解释的,但甚至没有帮助我理解)
我会分享我的代码,但是我不明白
namespace Delegates2 {
class Program {
static void Main(string[] args) {
Car mazda = new Car("Mazda");
Person chris = new Person();
mazda.Drive += chris.OnPersonDrive;
mazda.StartJourney();
Console.ReadKey();
}
}
public delegate void DriverCarEventHandler(object obj, EventArgs e);
public class Car
{
public string Name { get; }
public event DriverCarEventHandler Drive;
public Car(string name) {
Name = name;
}
public void StartJourney() {
OnDrive();
}
protected virtual void OnDrive() {
if (Drive != null) {
Drive(this, EventArgs.Empty);
}
}
}
public class Person
{
public void OnPersonDrive(Object source, EventArgs e) {
Console.WriteLine("Driving....");
}
}
}
以下是我所有的困惑......
答案 0 :(得分:2)
尽可能简短地解决您的问题,避免提出问题"过于宽泛" ......
•对象obj'和' EventArgs e'在委托声明中代表什么?对于学习似乎这些往往是空的。什么可能是这些可能需要不同的例子?
obj
应始终为非null,并应设置为引发事件的对象的引用。 e
应该是EventArgs
或派生类的实例,包含与事件相关的信息。
重要的是要注意这种模式严格是传统的。即不是由任何人强制执行,也不是必需的。 C#event
可以使用任何委托类型。 EventHandler
委托类型只是标准方式在.NET中实现事件的基础。
•当您基于委托创建事件时,事件现在是否存储了指向方法的所有指针,还是它仍然是委托?我听说过有关为活动添加订阅者的术语。这些用户是'只是方法与向代理添加方法的方式相同?
大多数事件都是由编译器隐式实现的。但了解当您使用event
关键字时,您要为该事件声明add
和remove
方法,这一点非常重要。这些类似于属性的get
和set
方法。默认实现只是接受传入的委托实例,并将其附加到事件的后备字段的现有值(也为您隐式生成),或者将其从add
和{{1方法分别。
事件的默认实现将其存储在一个简单的remove
类型字段中。事件的实现更复杂,例如将事件处理程序引用放在字典中,或使用弱引用。
•显然OnDrive()方法正在提升'事件。是'提高'与执行事件相同的事件?那么执行附加到事件的所有订户?
是的,举起一个活动只是调用已添加(订阅)该活动的代表。 .NET委托类型都是" multi-cast"委托,因此单个委托实例可以表示多个调用目标。调用一个委托实例将自动调用所有的各个调用目标。
按照惯例,名为delegate
的方法,其中OnXXX()
是某个事件的名称,将始终引发该事件。但是没有要求这样做。一个明显的例外是当事件字段为XXX
时,即没有订阅者订阅该事件。在那种情况下,显然事件没有提出。另一个更具体的现实示例是Winforms API中null
个对象公开的各种事件,它们对规则有几个例外(对于与视觉状态变化有关的事件,如当前字体,背景颜色,启用状态等),如果对象或其任何祖先对象(即父母,祖父母等)正处于被处置的过程中,则缩短事件提升逻辑并返回而不引发事件。 / p>
•为什么在举办活动时必须符合委托输入参数? (这,EventArgs.Empty)。不仅仅是需要匹配这种格式的订阅者吗?
要调用委托,代码必须将必要的参数传递给它,就像调用任何方法时需要将必要的参数传递给它一样(即使存在默认值,编译器也会生成必要的代码以确保提供所有参数值。
如果委托的调用者没有传递参数值,那么最终传递给目标方法的值将来自哪里?