c#中的delegate(委托)和event(事件)

委托: 托付其余人作这件事   ,包括 托付本身  ,即  一个方法 能够  调用 没有关系的其余方法 , 也能够 将委托传递过去 ,回调本身的方法 ,且 能够自定义参数 ,很是方便 互相传值, 适合解耦 关系。html

 示例:c#

       public delegate void ChangeMoney(object s, int n);   // 用 delegate  声明委托设计模式

 

   一、 调用 其余方法函数

           售卖 页面添加商品,添加 的 商品 在另外一个页面也能看见 。post

                 售卖页面 类里面 定义委托:url

                    //定义一个委托
                        public delegate void GetProductHander(List<MarkingModel> mlist);
                  // 将建立的委托和特定事件关联
                  public static event GetProductHander getproduct;spa

           //点击添加商品时  调用 委托方法:                .net

                   if(点击添加商品)设计

                      {     指针

                          getproduct.Invoke(_list);         

                   }     

             另外一个页面调用委托:

                          ProductSaleMarketing.getproduct += new ProductSaleMarketing.GetProductHander(GetList);

                           // 将 要调用的 GetList 方法 放到  getproduct  (从类里面点出来)后面。 以及实现 GetList 方法

                         private void GetList(List<MarkingModel> _mlist)
                        {

                        }

      2.  至关于回调方法

                  这个要在类外面定义委托 ,由于 回调  是 在其余页面实例化委托 ,调用 链接的方法。  谁在后边 后边调用谁。

         

public delegate void ChangeMoney(object s, int n);  // 在页面外边  声明委托   其余页面均可调用

public partial class TiHuoBill : BaseForm
{

                          //多窗口共用事件
                            private void sn_EveDelSelectNumber(object cash, int n)
                                {
                                    ChangePay(cash, n);
                                 }


                       //现金
                          private void btnCash_Click(object sender, EventArgs e)
                      {
                             var sn = new ShowNumber(7);
                                   sn.CardMoney = _daishou;
                                   sn.EveDelSelectNumber += sn_EveDelSelectNumber;  //  主要就是 这句话  委托在ShowNumber 页面 实例化了, +=   即  那个页面执行后  调用 sn_EveDelSelectNumber
                                   sn.ShowDialog();
                     }

}

   ShowNumber 页面 :

          public ChangeMoney EveDelSelectNumber;   //  实例化委托

                   // 肯定关闭页面的时候 

                   private void btnSure_Click(object sender, EventArgs e)
                     {

                                 EveDelSelectNumber(SelectMoney, SelectType);  // 调用委托 并传值   或者这种方式:   EveDelSelectNumber.Invoke(SelectMoney, SelectType);

                      }

 

         暂时发现 委托 可使用这两种方式

        其中  delegate  和 event  效果 是同样的  

     区别  :event与delegate的区别
 首先,经过加入event关键字,在编译的时候编译器会自动针对事件生成一个私有的字段(与此事件相关的委托),以及两个访问器方法,即add访问器方法以及remove访问器方法,用于对事件的注册及注销(对事件使用+=及-=操做时就是调用的这两个方法)。
我想大家的问题主要是,实际上声明一个委托类型的字段也能够实现这些功能。
实际上之因此采用event而不直接采用委托,实际上仍是为了封装。能够设想一下,若是直接采用公共的委托字段,类型外部就能够对此字段进行直接的操做了,好比将其直接赋值为null。
而使用event关键字就能够保证对事件的操做仅限于add访问器方法以及remove访问器方法(即只能使用+=及-=)

  

    在Msdn中,有一段话描述Delegate和Event之间的关系,其实很简单:

        声明事件:若要在类内声明事件,首先必须声明该事件的委托类型。

 

    委托还适用于 观察者模式:

                 

    class Program
    {
        static void Main(string[] args) { var car = new Car(15); new Alerter(car); car.Run(120); } } class Car { public delegate void Notify(int value); public event Notify notifier; private int petrol = 0; public int Petrol { get { return petrol; } set { petrol = value; if (petrol < 10) //当petrol的值小于10时,出发警报 { if (notifier != null) { notifier.Invoke(Petrol); } } } } public Car(int petrol) { Petrol = petrol; } public void Run(int speed) { int distance = 0; while (Petrol > 0) { Thread.Sleep(500); Petrol--; distance += speed; Console.WriteLine("Car is running... Distance is " + distance.ToString()); } } } class Alerter { public Alerter(Car car) { car.notifier += new Car.Notify(NotEnoughPetrol); } public void NotEnoughPetrol(int value) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("You only have " + value.ToString() + " gallon petrol left!"); Console.ResetColor(); } }

看完了上面的代码后,你可能会问:为何不在public int Petrol中直接调用Alerter.NotEnoughPetrol呢?由于Car模块和Alerter模块自己是两个独立的子系统,若是直接调用,耦合性就会增长,这不是咱们愿意看到的。

    其实以上的代码是设计模式中的观察者模式(观察者模式又称Source/Listener模式)的实现,当汽车在运行中汽油量<10时,警报器便会发出警报。在上面代码中,Delegate至关于一个存放回调函数的函数指针,使用Delegate,咱们能够很是方便地实现观察者模式。而其实,在须要使用回调函数时,咱们均可以考虑使用Delegate。

    不知道你有没有发如今上面的代码中还有一个问题呢?

public event Notify notifier;

上面的代码中,咱们定义了一个Event,而事实上:

public Notify notifier;

 

这样写,也彻底能够知足咱们的需求,这就引出了咱们的另外一个问题,Delegate和Event!  如上 有说明。

 

               参考:   谈C#中的Delegate

                             event与delegate的区别

                            终于会用c#中的delegate(委托)和event(事件)了

相关文章
相关标签/搜索