欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

C#委托与事件

程序员文章站 2022-05-06 10:05:44
...

理解委托

委托是对方法的引用.
平时我们调用方法是指定方法名。比如

Console.WriteLine("Hello World!");

委托对象引用了方法。就像将int值赋给int变量一样,是将方法赋给委托对象.
我们之前已经使用过委托了,比如List<T>类的Find方法。
List类使用委托执行的操作其他方法还有Max,Min
C#委托与事件
假如我们有一间工厂,有许多台机器,其中有折叠机,焊接机、彩印机.
我们要写一个控制程序来实现停机功能,如果不适用委托可以这样写:
C#委托与事件
如果工厂采购了新机器,我们就必须修改这些代码,因为Controller类和机器是紧密联系的,这样扩展性和灵活性都不好.

声明委托

我们可以通过委托来修改上面的代码

delegate void StopMachine();//声明委托类型

声明委托使用delegate关键字。
委托定义了它所引用的方法的形式,要指定返回类型委托名称以及任何参数.
定义好委托好,就可以创建它的示例,并用+= 操作符让该实例引用匹配的方法。

创建委托实例

下面就创建了委托实例

private StopMachine stopMachine;
        delegate void StopMachine();//声明委托类型
        private StopMachine stopMachine;

        public Controller()
        {
            stopMachine += folder.StopFolding;
        }

我们将机器停止的方法加到委托中,此时并没有调用方法.
注意:只需要指定方法名,不要包含圆括号或参数.
还可以用new关键字显示初始化委:

stopMachine = new StopMachine(folder.StopFolding);

可以通过调用委托来调用它引用的方法:
C#委托与事件
委托的优势在于它能够引用多个方法。
C#委托与事件
在Stop方法中调用stopMachine,将依次调用上述每一个方法。
使用-=,可以从委托中移除一个方法.

stopMachine -= painter.PaintOff;
            Controller controller = new Controller();
            FoldingMachine folder = new FoldingMachine();
            WeldingMachine welder = new WeldingMachine();
            PaintingMachine painter = new PaintingMachine();

            controller.Add(folder.StopFolding);
            controller.Add(welder.FinishWelding);
            controller.Add(painter.PaintOff);
            controller.Stop();

通过委托我们就减少了耦合性,这就是委托的一个作用.



Lambda表达式和委托

前面我们使用下面的方式来向委托添加方法:

stopMachine += folder.StopFolding;

对于和委托签名匹配的方法,这样写合适,但如果情况有变呢?
假如stopFolding实际签名如下:

void StopFolding(int time);//指定数秒后停机

该怎么办呢?不能在拿同一个委托处理全部三个方法了

创建方法适配器

一个解决方案是 创建另一个方法,在内部调用StopFolding:

void FinishFolding()
{
	folder.StopFolding(0);//立即停机
}

然后添加到委托中:

stopMachine += folder.FinishFolding;

C#针对这种情况提供了Lambda表达式,我们可以这样使用:

stopMachine += (()=>folder.StopFolding(0));



事件

许多时候需要在发生某事时自动运行委托。比如,在自动化工厂中,一台机器发生了故障应该马上调用委托来关闭设备.
.NEt 提供了事件,可定义并捕捉特定的事件,并在事件发生时调用委托进行处理.

声明事件

声明事件和声明字段相似。由于事件随委托使用,所以事件的类型必须是委托,而且必须在声明前附加event前缀:

event delegateTypeName eventName

比如,我们创建一个温度监视器类,该类为监视设备温度的各种电子探头提供了接口

    class TemperatureMonitor
    {
        public delegate void StopMachine();
        public event StopMachine MachineOverheating;
        ...
    }

要把方法添加到事件中-这个过程称为订阅事件

订阅事件

类似于委托,我们使用+=操作符订阅事件。

monitor.MachineOverheating += welder.FinishWelding;
monitor.MachineOverheating += painter.PaintOff;

类似的 我们使用-=操作符用于取消订阅

引发事件

事件可以像方法一样通过调用来引发。
C#委托与事件

相关标签: C# 委托 事件