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 两个方法,则进一步证明了我们对事件的定义:编译器生成了两个公有方法,来解决私有化委托后,外部无法为其增加或减少委托方法的问题

时间: 2024-08-03 17:41:24

C# 基于委托的事件的相关文章

委托与事件

委托在底层就是一个函数的指针,委托是事件的基础. 你可以传递引用类型.值类型.但是你有没有需要传一个方法呢?传方法的过程就是委托. 消息类: public class Message { /// <summary> /// 传引用类型 /// </summary> /// <param name="msg"></param> public static void Send(string msg) { Console.WriteLine(&

C#中委托和事件

目 录 1.1 理解委托 2 1.1.1 将方法作为方法的参数 2 1.1.2 将方法绑定到委托 4 1.2 事件的由来 6 1.2.1 更好的封装性 6 1.2.2 限制类型能力 9 1.3 委托的编译代码 10 1.4 .NET 框架中的委托和事件 11 1.4.1 范例说明 11 1.4.2 Observer 设计模式简介 12 1.4.3 实现范例的Observer 设计模式 13 1.4.4 .NET 框架中的委托与事件 14 1.5 委托进阶 16 1.5.1 为什么委托定义的返回值

委托和事件

一.委托:是一个能够引用方法的对象.创建委托时实际是创建一个方法引用的对象,创建的引用对象能够调用方法. 委托调用可以调用不同的方法,只需改变方法的引用即可.即委托调用方法是运行时确定,而非编译时确定. 就像声名一个object实例一样,声名的只是一个占位符,具体指向哪个对象在运行时可以动态指定.在委托中指定方法有限制:返回值,参数类型要相同. 委托声名:delegate ret-type delegatename(parameter-list) delegate 关键字声名委托 ret-typ

[转载]C#委托和事件(Delegate、Event、EventHandler、EventArgs)

原文链接:http://blog.csdn.net/zwj7612356/article/details/8272520 14.1.委托 当要把方法作为实参传送给其他方法的形参时,形参需要使用委托.委托是一个类型,是一个函数指针类型,这个类型将该委托的实例化对象所能指向的函数的细节封装起来了,即规定了所能指向的函数的签名,也就是限制了所能指向的函数的参数和返回值.当实例化委托的时候,委托对象会指向某一个匹配的函数,实质就是将函数的地址赋值给了该委托的对象,然后就可以通过该委托对象来调用所指向的函

.NET基础拾遗(4)委托、事件、反射与特性

Index : (1)类型语法.内存管理和垃圾回收基础 (2)面向对象的实现和异常的处理基础 (3)字符串.集合与流 (4)委托.事件.反射与特性 一.委托基础 1.1 简述委托的基本原理 委托这个概念对C++程序员来说并不陌生,因为它和C++中的函数指针非常类似,很多码农也喜欢称委托为安全的函数指针.无论这一说法是否正确,委托的的确确实现了和函数指针类似的功能,那就是提供了程序回调指定方法的机制. 在委托内部,包含了一个指向某个方法的指针(这一点上委托实现机制和C++的函数指针一致),为何称其

转:委托和事件详解

Delegate delegate是C#中的一种类型,它实际上是一个能够持有对某个方法的引用的类.与其它的类不同,delegate类能够拥有一个签名(signature),并且它"只能持有与它的签名相匹配的方法的引用".它所实现的功能与C/C++中的函数指针十分相似.它允许你传递一个类A的方法m给另一个类B的对象,使得类B的对象能够调用这个方法m.但与函数指针相比,delegate有许多函数委托和事件在 .Net Framework中的应用非常广泛指针不具备的优点.首先,函数指针只能指

C# 委托和事件(一):最简单的委托和事件

C#的事件基于委托,所以先说委托. 一切脱离实际场景的抽象概念新手看上去就像是在扯犊子,不错,我就是个新手.所以我需要一个实际的场景. 明天刚好考试(商务英语),考试上有两个角色(class):老师(Teacher)和学生(Student),在考试时间终止的时候,老师会触发(invoke)一个事件(event):"考试时间到了,我tm要收卷子了!"(OnTestTimeUp),而每个学生都要订阅这个事件,并在这个事件发生的时候上交试卷(HandInTestPaper).如果不用事件的话

委托、事件与回调函数(续)

C#中的委托和事件(续) --此篇来自于Jimmy Zhang的随手记!本人觉得讲的很详细很值得推荐 引言 如果你看过了 C#中的委托和事件 一文,我想你对委托和事件已经有了一个基本的认识.但那些远不是委托和事件的全部内容,还有很多的地方没有涉及.本文将讨论委托和事件一些更为细节的问题,包括一些大家常问到的问题,以及事件访问器.异常处理.超时处理和异步方法调用等内容. 为什么要使用事件而不是委托变量? 在 C#中的委托和事件 中,我提出了两个为什么在类型中使用事件向外部提供方法注册,而不是直接使

c#委托和事件(下)

C#中的委托和事件(下) 引言 如果你看过了 C#中的委托和事件 一文,我想你对委托和事件已经有了一个基本的认识.但那些远不是委托和事件的全部内容,还有很多的地方没有涉及.本文将讨论委托和事件一些更为细节的问题,包括一些大家常问到的问题,以及事件访问器.异常处理.超时处理和异步方法调用等内容. 为什么要使用事件而不是委托变量? 在 C#中的委托和事件 中,我提出了两个为什么在类型中使用事件向外部提供方法注册,而不是直接使用委托变量的原因.主要是从封装性和易用性上去考虑,但是还漏掉了一点,事件应该