代表们如何与活动相关联?

时间:2017-03-09 08:12:46

标签: c# events delegates

我已经阅读了很多关于代表和事件的材料和示例,但我真的很难理解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....");
        } 
    }
} 

以下是我所有的困惑......

  • 委托声明中的'Object obj'和'EventArgs e'是什么? 代表?对于学习似乎这些往往是空的。什么可能是这些可能需要不同的例子?
  • 当您基于委托创建活动时,请执行此操作 event现在存储所有指向方法的指针,或者它仍然存在 代表?我听说过有关添加订阅者的术语 事件。这些“订阅者”的方法是否与您一样 向委托添加方法?
  • 显然,OnDrive()方法正在“提升”事件。 “提升”事件与执行事件相同 事件?那么执行附加到事件的所有订户?
  • 为什么当你举起一个活动时,它必须符合 委托输入参数? (这,EventArgs.Empty)。不是吗? 仅需要匹配此格式的订阅者?

1 个答案:

答案 0 :(得分:2)

尽可能简短地解决您的问题,避免提出问题"过于宽泛" ......

  

•对象obj'和' EventArgs e'在委托声明中代表什么?对于学习似乎这些往往是空的。什么可能是这些可能需要不同的例子?

obj应始终为非null,并应设置为引发事件的对象的引用。 e应该是EventArgs或派生类的实例,包含与事件相关的信息。

重要的是要注意这种模式严格是传统的。即不是由任何人强制执行,也不是必需的。 C#event可以使用任何委托类型。 EventHandler委托类型只是标准方式在.NET中实现事件的基础。

  

•当您基于委托创建事件时,事件现在是否存储了指向方法的所有指针,还是它仍然是委托?我听说过有关为活动添加订阅者的术语。这些用户是'只是方法与向代理添加方法的方式相同?

大多数事件都是由编译器隐式实现的。但了解当您使用event关键字时,您要为该事件声明addremove方法,这一点非常重要。这些类似于属性的getset方法。默认实现只是接受传入的委托实例,并将其附加到事件的后备字段的现有值(也为您隐式生成),或者将其从add和{{1方法分别。

事件的默认实现将其存储在一个简单的remove类型字段中。事件的实现更复杂,例如将事件处理程序引用放在字典中,或使用弱引用。

  

•显然OnDrive()方法正在提升'事件。是'提高'与执行事件相同的事件?那么执行附加到事件的所有订户?

是的,举起一个活动只是调用已添加(订阅)该活动的代表。 .NET委托类型都是" multi-cast"委托,因此单个委托实例可以表示多个调用目标。调用一个委托实例将自动调用所有的各个调用目标。

按照惯例,名为delegate的方法,其中OnXXX()是某个事件的名称,将始终引发该事件。但是没有要求这样做。一个明显的例外是当事件字段为XXX时,即没有订阅者订阅该事件。在那种情况下,显然事件没有提出。另一个更具体的现实示例是Winforms API中null个对象公开的各种事件,它们对规则有几个例外(对于与视觉状态变化有关的事件,如当前字体,背景颜色,启用状态等),如果对象或其任何祖先对象(即父母,祖父母等)正处于被处置的过程中,则缩短事件提升逻辑并返回而不引发事件。 / p>

  

•为什么在举办活动时必须符合委托输入参数? (这,EventArgs.Empty)。不仅仅是需要匹配这种格式的订阅者吗?

要调用委托,代码必须将必要的参数传递给它,就像调用任何方法时需要将必要的参数传递给它一样(即使存在默认值,编译器也会生成必要的代码以确保提供所有参数值。

如果委托的调用者没有传递参数值,那么最终传递给目标方法的值将来自哪里?