C# - 委托与事件


C# - 委托与事件

什么是委托

委托(delegate)

  • 自己不动手,而是交代给别人替你去完成。
  • 委托就是方法指针,仅仅指向方法的名称,不表示具体执行过程。
  • 方法指针是一种数据类型,它所处理的是方法引用过程的类型。
  • 委托必须与被委托的方法“类型兼容”。

实例

namespace HelloWorld
{
    //委托delegate
    public delegate void PhotoFilterHandler(Photo photo);
    
    public class PhotoProcessor
    {
        public void Process(Photo photo, PhotoFilterHandler filterHandler)
        {
            //委托delegate传值
            filterHandler(photo);
            photo.Save();
        }
    }
}

实例2 —— 多播委托Multicast

using System;
using System.Text;
using static HelloWorld.PhotoProcessor;

namespace HelloWorld
{
    class Program
    {
        static void RedEyesRemovalFilter(Photo photo)
        {
            Console.WriteLine("去除红颜");
        }

        static void Main(string[] args)
        {
            var photo = Photo.load("phtot.jpg");

            var filters = new PhotoFilters();

            PhotoFilterHandler filterHandler = filters.ApplyBrightness;

            //多播委托 Multicast
            filterHandler += filters.ApplyContrast;
            filterHandler += filters.Resize;
            filterHandler += RedEyesRemovalFilter;

            var processor = new PhotoProcessor();
            processor.Process(photo, filterHandler);

            Console.Read();
        }
    }
}

预定义委托方法Func、Action

System.Action<> 没有返回值

实例

using System;
using System.Text;

namespace HelloWorld
{
    class Program
    {
        static void Main(string[] args)
        {
            var photo = Photo.load("photo.jpg");

            var processor = new PhotoProcessor();

            var filters = new PhotoFilters();

            // System.Action<> 没有返回值
            Action<Photo> filterHandler = filters.ApplyBrightness;
            filterHandler += filters.ApplyContrast;
            filterHandler += filters.Resize;
            filterHandler += RemoveRedEyesFilter;

            processor.Process(photo, filterHandler);

            Console.Read();
        }

        static void RemoveRedEyesFilter(Photo photo)
        {
            Console.WriteLine("去除红眼");
        }
    }
}

实例2

using System;

namespace HelloWorld
{
    // System.Action<> 没有返回值
    // System.Func<>有返回值

    public class PhotoProcessor
    {
        // System.Action
        public void Process(Photo photo, Action<Photo> filterHandler)
        {
            filterHandler(photo);
            photo.Save();
        }
    }
}

System.Func<> 有返回值

C#预定义事件

数据、操作、以及通知

  • 小闪电,成员事件
  • 扳手,成员属性
  • 立方体,成员方法

实例(闹钟)

using System;
using System.Timers;
using Timer = System.Timers.Timer;

namespace HelloWorld
{
    public class Alex
    {
        internal void AlarmEventHandler(object sender, ElapsedEventArgs e)
        {
            Console.WriteLine("闹钟响了, 我不管");
        }
    }

    public class RoomMate
    {
        public int RageValue { get; set; }

        internal void AlarmEventHandler(object sender, ElapsedEventArgs e)
        {
            RageValue += 25;
            if (RageValue >= 100)
            {
                Console.WriteLine("受不了了");
                ((Timer)sender).Stop();
            }
            Console.WriteLine("闹钟响了, 我也不管");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Timer timer = new Timer();
            timer.Interval = 1000;

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

            timer.Start();

            Console.Read();
        }
    }
}

自定义事件

event-in-general,事件的完整声明

实例

OrderProcessor.cs

using System;
using System.Collections.Generic;

namespace HelloWord
{
    //EventArgs是包含事件数据的类的基类,用于传递事件的细节
    public class OrderProcessorEventArgs : EventArgs
    {
        public string Status { get; set; }
        public DateTime ProcessingTime { get; set; }
        public string Desctiption { get; set; }
    }

    //声明委托delegate
    //EventHandler
                                                     //传入的两个参数 Order order, OrderProcessorEventArgs args
    public delegate void OrderProcessorEventHandler(Order order, OrderProcessorEventArgs args);

    public class OrderProcessor
    {
        //事件约束
        private OrderProcessorEventHandler _orderProcessorEventHandler;

        public event OrderProcessorEventHandler OrderProcessorEvent
        {
            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);
            }
        }
    }
}

Program.cs

using System;
using System.Collections;
using System.Collections.Generic;

namespace HelloWord
{
    class Program
    {
        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();
        }
    }
}

MailService.cs(事件响应者)

using System;

namespace HelloWord
{
    internal class MailService
    {
        internal static void OnOrderProcessed(Order order, OrderProcessorEventArgs args)
        {
            Console.WriteLine($"发送邮件,订单 {order.Id} , 处理结果: {args.Status}, 处理时间: {args.ProcessingTime}");
        }
    }
}

SmsMessageService.cs(事件响应者)

using System;
namespace HelloWord
{
    public class SmsMessageService
    {
        internal static void OnOrderProcessed(Order order, OrderProcessorEventArgs args)
        {
            Console.WriteLine($"发送短信,订单 {order.Id} , 处理结果: {args.Status}, 处理时间: {args.ProcessingTime}");
        }
    }
}

Order.cs

using System;

namespace HelloWord
{
    public class Order
    {
        public int Id { get; set; }
        public DateTime DatePlaced { get; set; }
        public float TotalPrice { get; set; }
        public bool IsShipped { get; set; }
    }
}

测试

field-like,字段式声明(下一节)

字段式事件声明(field-like)

field-like,字段式声明

实例

OrderProcessor.cs

using System;
using System.Collections.Generic;

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

    public class OrderProcessor
    {

        //预定义事件 EventHandler
        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);
            }
        }
    }
}

声明:三二一的一的二|版权所有,违者必究|如未注明,均为原创|本网站采用BY-NC-SA协议进行授权

转载:转载请注明原文链接 - C# - 委托与事件


三二一的一的二