C#委托,事件最初浅的和最易看懂的学习笔记

Posted 剧里局外

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#委托,事件最初浅的和最易看懂的学习笔记相关的知识,希望对你有一定的参考价值。

     对于委托和事件,看了不少博文,当时好像都理解了,过了一段时间,又忘记的差不多了。每每如此,感觉自己很笨,记性差,其实是没有深入理解透切,没有按照自己的语言表达出来,当然容易忘记。今天又花了一些时间,好好理解,总结别人的文章,用自己文字概况出来。

    

    总结如下:

委托可以定义任何地方,应该说是委托声明

事件类可以单独放一个地方,包含一些属性

事件一定定义在发布者里面,应该说是事件声明,并在这里做判断注册事件,给事件类属性赋值

订阅者,也就是事件的受理者,它里面有些方法并后续操作。

客户端把发布者与订阅者关联起来。
发布者.事件+=订阅者.方法
或者
发布者.事件+=new 委托声明类.委托(订阅者.方法)
发布者.方法--调用事件的方法

 代码实例

发布者

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace dazilianxi.deleteevent
{
    //商家,发布商品肯定包含一些属性,就是给商品赋值实例化
    public class Provider
    {
        public delegate void DaZheEventHandler(object sender, ProductEventArgs e);//声明委托
        public event DaZheEventHandler DaZhe;//声明事件

        
        protected virtual void FaBuChanPin(ProductEventArgs e)
        {
            if (DaZhe != null)
            {
                this.DaZhe(this, e);//注册事件
            }
        }
        private decimal price = 18000M;
        public void ShangJia(int discout) {//事件赋值
           this.FaBuChanPin(new ProductEventArgs { Price = discout*price/10, ProAddress = "中国广东", ProName = "红日电器", Discount = discout });
        }
    }
}

事件类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace dazilianxi.deleteevent
{
    //事件类,包含商品一些属性
    public class ProductEventArgs : EventArgs
    {
        public decimal Price { get; set; }
        public string ProName { get; set; }
        public string ProAddress { get; set; }
        public int Discount { get; set; }
    }
}

订阅者

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace dazilianxi.deleteevent
{//就是我们,我们有购买行为(方法)
    public class Custome
    {
        public void OnGouMai(object sender,ProductEventArgs e) 
        {
            if (e.Price < 15000M)
            {
                Console.WriteLine("大家快了买,产于" + e.ProAddress + "" + e.ProName + "" + e.Discount + "折了。目前价格是" + e.ProName + "很划算了");
            }
            else {
                OnGuanKan();
            }
        }

        public void OnGuanKan()
        {
            Console.WriteLine("再等等看!");
        }
    }
}

 

客户端

class Program
    {
        static void Main(string[] args)
        {
            //客户端二者关联
            Provider shangjia = new Provider();
            shangjia.DaZhe += new Provider.DaZheEventHandler(new Custome().OnGouMai);//第一种方式
            shangjia.ShangJia(2);

            Provider shangjia2 = new Provider();
            shangjia2.DaZhe += new Custome().OnGouMai;//第二种方式
            shangjia2.ShangJia(9);
       }
}

结果图

 

 

补充

封装就是将某个属性放到某个类里面,然后通过类去调用,好比黑盒测试一样
注意这里,第一次用的“=”,是赋值的语法;第二次,用的是“+=”,是绑定的语法。如果第一次就使用“+=”,将出现“使用了未赋值的局部变量”的编译错误。
最后,第一个方法注册用“=”,是赋值语法,因为要进行实例化,第二个方法注册则用的是“+=”。但是,不管是赋值还是注册,都是将方法绑定到委托上,除了调用时先后顺序不同,再没有任何的分别,这样不是让人觉得很别扭么?
1什么是委托和事件
委托就是将方法作为方法的参数,委托是一种特殊的类

声明委托
public delegate void foo (string param);

委托绑定方法
使用委托可以将多个方法绑定到同一个委托变量,当调用此变量时,可以依次条用所有绑定的方法。

2什么是事件
于是,Event 出场了,它封装了委托类型的变量,使得:在类的内部,不管你声明它是public还是protected,它总是private 的。在类的外部,注册“+=”和注销“-=”的访问限定符与你在声明事件时使用的访问符相同。

声明事件
声明一个事件不过类似于声明一个进行了封装的委托类型变量而已。事件可以约束客户端的能力。
使用事件不仅能获得比委托更好的封装性以外,还能限制含有事件的类型的能力。这是什么意思呢?它的意思是说:事件应该由事件发布者触发,而不应该由事件的客户端(客户程序)来触发。
这里还有一个约定俗称的规定,就是订阅事件的方法的命名,通常为“On 事件名”,比如这里的OnNumberChanged。http://www.cnblogs.com/SkySoot/archive/2012/04/05/2433639.html

参考:

http://www.cnblogs.com/wudiwushen/archive/2010/04/23/1717829.html

http://www.cnblogs.com/jimmyzhang/archive/2007/09/23/903360.html

 

以上是关于C#委托,事件最初浅的和最易看懂的学习笔记的主要内容,如果未能解决你的问题,请参考以下文章

30秒就能看懂的JavaScript 代码片段

事件委托

C#学习之初步理解委托事件匿名方法和Lambda

C#笔记-委托&事件

读书笔记 C#事件event浅析

分分钟用上C#中的委托和事件