C# 基于委托的事件

  事件基于多播委托的特性。

  多播委托事实上就是一组类型安全的函数指针管理器,调用则执行顺序跳转到数组里所有的函数指针里执行。

    class Program
    {
        public class CarInfoEventArgs : EventArgs
        {
            public string Car { get; set; }

            public CarInfoEventArgs(string car)
            {
                this.Car = car;
            }
        }

        public class CarDealer
        {
            public event EventHandler<CarInfoEventArgs> NewCarInfo;   //使用系统定义的泛型委托

            public void NewCarcComing(string car)
            {
                Console.WriteLine("CarDealer, new car {0} has come.", car);

                EventHandler<CarInfoEventArgs> newCarInfo = NewCarInfo;
                if (newCarInfo != null)
                    NewCarInfo(this, new CarInfoEventArgs(car));
            }
        }

        public class Consumer
        {
            private string name;

            public Consumer(string name)
            {
                this.name = name;
            }

            public void NewCarIsHere(object sender, CarInfoEventArgs e)
            {
                Console.WriteLine("{0}, car {1} is new", name, e.Car);
            }
        }

        static void Main(string[] args)
        {
            var dealer = new CarDealer();
            var personA = new Consumer("personA");
            dealer.NewCarInfo += personA.NewCarIsHere;
            dealer.NewCarcComing("Ferrari");

            var personB = new Consumer("personB");
            dealer.NewCarInfo += personB.NewCarIsHere;
            dealer.NewCarcComing("BMW");

            Console.ReadLine();
        }
    }

   

  基于该例,我们用“多播委托”的概念来重写:

    class Program
    {
        public class CarDealer
        {
            public Action<string> NewCarInfo;   //使用系统定义的泛型委托

            public void NewCarComing(string car)
            {
                Console.WriteLine("CarDealer, new car {0} has come.", car);

                if (NewCarInfo != null)
                    NewCarInfo(car);
            }
        }

        public class Consumer
        {
            private string name;

            public Consumer(string name)
            {
                this.name = name;
            }

            public void NewCarIsHere(string car)
            {
                Console.WriteLine("{0}, car {1} is new", name, car);
            }
        }

        static void Main(string[] args)
        {
            var dealer = new CarDealer();
            var personA = new Consumer("personA");
            dealer.NewCarInfo += personA.NewCarIsHere;
            dealer.NewCarComing("Ferrari");

            var personB = new Consumer("personB");
            dealer.NewCarInfo += personB.NewCarIsHere;
            dealer.NewCarComing("BMW");

            Console.ReadLine();
        }
    }

 

  我只想知道,在多播委托的基础上,事件有哪些自身的特性?从以上两个例子中似乎看不出来。

  继续来看下一个例子:

    class Program
    {
        public class CarDealer
        {
            public event Action<string> NewCarInfo;   //使用系统定义的泛型委托

            public void NewCarComing(string car)
            {
                Console.WriteLine("CarDealer, new car {0} has come.", car);

                if (NewCarInfo != null)
                    NewCarInfo(car);
            }
        }

        public class Consumer
        {
            private string name;

            public Consumer(string name)
            {
                this.name = name;
            }

            public void NewCarIsHere(string car)
            {
                Console.WriteLine("{0}, car {1} is new", name, car);
            }
        }

        static void Main(string[] args)
        {
            var dealer = new CarDealer();
            var personA = new Consumer("personA");
            dealer.NewCarInfo += personA.NewCarIsHere;
            dealer.NewCarInfo("Ferrari");

            var personB = new Consumer("personB");
            dealer.NewCarInfo += personB.NewCarIsHere;
            dealer.NewCarInfo("BMW");

            Console.ReadLine();
        }
    }

  1. 我们在委托之前加上“event”关键字;

  2. 我们在外部直接调用 委托实例;

  这个例子是编译不过的,由此可知 “event” 是不能直接由外部访问的。将该实例的 “event” 关键字拿掉,则可以编译通过。

 

    class Program
    {
        public class CarDealer
        {
            public event Action<string> NewCarInfo;   //使用系统定义的泛型委托

            public void NewCarComing(string car)
            {
                Console.WriteLine("CarDealer, new car {0} has come.", car);

                if (NewCarInfo != null)
                    NewCarInfo(car);
            }
        }

        public class Consumer
        {
            private string name;

            public Consumer(string name)
            {
                this.name = name;
            }

            public void NewCarIsHere(string car)
            {
                Console.WriteLine("{0}, car {1} is new", name, car);
            }
        }

        static void Main(string[] args)
        {
            var dealer = new CarDealer();
            var personA = new Consumer("personA");
            dealer.NewCarInfo += personA.NewCarIsHere;
            dealer.NewCarComing("Ferrari");

            var personB = new Consumer("personB");
            dealer.NewCarInfo += personB.NewCarIsHere;
            dealer.NewCarComing("BMW");

            Console.ReadLine();
        }
    }

  将         dealer.NewCarInfo("BMW");

      改为了   dealer.NewCarComing("BMW");

  则可以编译通过,说明:委托实例是可以直接调用委托方法的,而事件则需要进一步封装,由此可知,事件是将委托方法私有化的封装

 

  再通过 反编译器 检查exe:

  可以看到,增加了 add_NewCarInfo, remove_NewCarInfo 两个方法,则进一步证明了我们对事件的定义:编译器生成了两个公有方法,来解决私有化委托后,外部无法为其增加或减少委托方法的问题

posted on 2016-08-10 10:51  青墨淡潋  阅读(290)  评论(0)    收藏  举报