.NET 事件

  事件分为发布器和订阅器
  发布器是包含委托定义和事件对象定义的类
  订阅器需要实现发布器约束的参数和返回值,也就是void返回并传一个发布器类型的参数和一个事件信息参数
  事件信息必须继承于EventArgs,用于存事件需要的信息,订阅器通过事件信息参数完成事件的处理
  事件和委托最大的区别,同时也是最大的作用,事件只能在发布器内调用委托里的方法,发布器外部只能添加和删除,也就是如果不从外部传参数,外部无法干扰到发布器类调用的参数

class Program
    {

        static void Main(string[] args)
        {//创建发布器对象
            Customer lrp = new Customer();
            Customer luncy = new Customer();
            //创建订阅器对象
            Cashier cashier = new Cashier();
            //注册订阅器对象
            lrp.Order += cashier.Closing;
            luncy.Order += cashier.Closing;
            lrp.Shopping("肥皂", 3, 10);
            lrp.Shopping("水桶", 2, 20);
            luncy.Shopping("毛巾", 3, 5);
            luncy.Shopping("雪糕", 4, 1);

            //调用事件
            Console.Write("lrp,");
            lrp.Action();
            Console.Write("luncy,");
            luncy.Action();
        }
    }

    public class GoodsAgrs : EventArgs//事件信息,存储货物信息和货物数量
    {
        private List<string> _goodName = new List<string>();
        private List<int> _goodPrice = new List<int>();
        private List<int> _goodNumber = new List<int>();
        public List<string> GoodName
        {
            get
            {
                return this._goodName;
            }
            set
            {
                this._goodName = value;
            }
        }
        public List<int> GoodPrice {
            get
            {
                return this._goodPrice;
            }
            set
            {
                this._goodPrice = value;
            }
        }
        public List<int> GoodNumber {
            get
            {
                return this._goodNumber;
            }
            set
            {
                this._goodNumber = value;
            }
        }
        public int TotalPrice { get; set; }
    }

    public class Customer//发布器,调用订阅器处理事件信息
    {
        public event EventHandler Order;
        public void Action()
        {
            if (Order != null)
            {
                Order(this, goods);
            }
        }
        private GoodsAgrs goods = new GoodsAgrs();
        public void Shopping(string goodName, int goodNumber, int goodPrice)
        {
            goods.GoodName.Add(goodName);
            goods.GoodNumber.Add(goodNumber);
            goods.GoodPrice.Add(goodPrice);
        }
    }

    public class Cashier//订阅器,处理事件信息
    {
        public void Closing(object sender, EventArgs e)
        {
            Customer cashier = sender as Customer;
            GoodsAgrs goodsAgrs = e as GoodsAgrs;
            Console.WriteLine("您购买了");
            for (int i = 0; i < goodsAgrs.GoodPrice.Count; i++)
            {
                goodsAgrs.TotalPrice += goodsAgrs.GoodNumber[i] * goodsAgrs.GoodPrice[i];
                Console.WriteLine("{0}*{1}", goodsAgrs.GoodName[i], goodsAgrs.GoodNumber[i]);
            }
            Console.WriteLine("您需要支付{0}元", goodsAgrs.TotalPrice);
        }
    }

  如果换成普通的委托也同样可以完成整个事件,但事件约束了委托在外部的使用,在外部事件定义的委托只能出现在+=或-=的左边,也就是只能添加和移除,如果外部可以直接调用事件并传入参数,那么上面的例子可能就会出现lrp.Order(lrp,luncy.goods)这种情况,所以事件就是一种约束,防止出现乱传参数的情况,保证程序的安全运行。

posted @ 2022-10-03 08:58  lrplrplrp  阅读(98)  评论(0编辑  收藏  举报