委托和事件

90 阅读3分钟

委托delegate

委托是一个类而不是方法,但是委托声明在类内类外都不影响

public delegate void PhotoFilterHandler(Photo photo); 

public void Process(Photo photo, PhotoFilterHandler filterHandler)
{
    filterHandler(photo);
    photo.Save();
}

使用委托后,图片的处理过程将放在图片处理器的外部并且由图片处理器的调用方负责加载 委托是方法的指针,指向被委托方法的内存地址,被委托方法的签名需要与委托方法的签名一致 创建委托实例不需要使用new关键字,使用=直接指向一个可以工作的方法

var filters = new PhotoFilters();
PhotoFilterHandler filterHandler = filters.ApplyBrightness;
//使用+=操作符可以实现一个多播委托,是委托的叠加使用
filterHandler += filters.ApplyContrast;
filterHandler += filters.Resize;

预定义委托方法Func和Action

Func方法有返回值,Action方法没有返回值,被委托方法有几个参数,就使用几个泛型的Func或Action,最多可以有16个参数

public void Process(Photo photo, Action<Photo> filterHandler)
{
    filterHandler(photo);
    photo.Save();
}
Action<Photo> filterHandler = filters.ApplyBrightness;

C#预定义方法

数据操作及通知 扳手:成员属性,表示当前类处于什么状态,存储数据。 立方体:成员方法,表示他能做什么,业务操作。 闪电:事件、通知,表示它能在什么情况下向事件的订阅用户发送通知

事件的五要素:事件拥有者,事件,事件订阅者(响应对象),事件处理器,事件订阅(+=操作符)

Timer timer = new Timer();
timer.Interval = 1000;

var alex = new Alex();
timer.Elapsed += alex.AlarmEventHandler;

timer.Start();


public class Alex
{
    //sender就是事件的发出方,即事件拥有者,可以通过 var timer = (Timer)sender取得事件
    internal void AlarmEventHandler(object sender, ElapsedEventArgs e)
    {
        Console.WriteLine("闹钟响了, 我不管");
    }
}

自定义事件

事件的完整申明

//事件信息参数类,需要以EventArgs结尾,这个类需要继承事件参数的基类
public class OrderProcessorEventArgs : EventArgs
{
    public string Status { get; set; }
    public DateTime ProcessingTime { get; set; }
    public string Desctiption { get; set; }
}
//需要在使用事件或委托时以EventHandler结尾
//自定义事件                                          传入订单             事件信息参数
public delegate void OrderProcessorEventHandler(Order order, OrderProcessorEventArgs args);


public class OrderProcessor
{
//_orderProcessorEventHandler用于保存/引用外部事件处理器(不希望被外部访问)
    private OrderProcessorEventHandler _orderProcessorEventHandler;
// 事件(希望能被外部访问)
    public event OrderProcessorEventHandler OrderProcessorEvent
    {
        // add添加事件引用,remove删除事件引用
        add
        {
            this._orderProcessorEventHandler += value;
        }
        remove
        {
            this._orderProcessorEventHandler -= value;
        }
    }
            public void Process(Order order)
        {
            // 订单处理...

            // 订单处理完成,发送订单处理完成事件
            if (_orderProcessorEventHandler != null)
            {
                var e = new OrderProcessorEventArgs
                {
                    Status = "completed",
                    ProcessingTime = DateTime.UtcNow,
                    Desctiption = "处理得非常成功"
                };
                _orderProcessorEventHandler(order, e);
            }
        }
     }
//主程序
static void Main(string[] args)
{
    var order = new Order
    {
        Id = 123,
        DatePlaced = DateTime.Now,
        TotalPrice = 30f
    };

    OrderProcessor orderProcessor = new OrderProcessor();

    orderProcessor.OrderProcessorEvent += SmsMessageService.OnOrderProcessed;
    orderProcessor.OrderProcessorEvent += MailService.OnOrderProcessed;

    orderProcessor.Process(order);

    Console.Read();
}

字段式声明

  public class OrderProcessorEventArgs : EventArgs
    {
        public string Status { get; set; }
        public DateTime ProcessingTime { get; set; }
        public string Desctiption { get; set; }
    }

    public class OrderProcessor
    {
        //预定义事件
        public event EventHandler<OrderProcessorEventArgs> OrderProcessorEvent;

        public void Process(Order order)
        {
            // 订单处理...

            // 订单处理完成,发送订单处理完成事件
            //直接使用事件完成处理
            if (OrderProcessorEvent != null)
            {
                var e = new OrderProcessorEventArgs
                {
                    Status = "completed",
                    ProcessingTime = DateTime.UtcNow,
                    Desctiption = "处理得非常成功"
                };
                OrderProcessorEvent(order, e);
            }
        }
    }
    
    //短信处理服务
internal class MailService
{
//参数:完整声明时,参数为Order order,字段式声明时需要使用object对象并且转换类型
    internal static void OnOrderProcessed(object sender, OrderProcessorEventArgs args)
    {
        //类型转换
        var order = (Order)sender;
        Console.WriteLine($"发送邮件,订单 {order.Id} , 处理结果: {args.Status}, 处理时间: {args.ProcessingTime}");
    }
}