C#委托和事件理解

       C#中委托和时间是个坎,了解的人绝的就是那么回事,没吃透的人总是觉的碰见一次迷糊一次,我就是接与两者之间,也算站在坎上,但是稍稍理解了一些,希望通过这篇文章,让迷茫的同学,稍微的理解一下。

在这里推荐Jimmy Zhang(张子阳)的一篇博文C# 中的委托和事件,他讲解的非常好,比书上那些概念罗列要出色的多。推荐大家看一下,到时候应该会理解很深,我写这个博文的原因是主要是为了让自己理解一下,日后可以翻看一下。

OK,首先还是说一下委托的概念,《C#高级编程》当头一句,委托是寻址方法的.Net版本。为了好理解就是可以认为是方法指针(当然往上有些人不推荐,说高级程序员都不是这么理解的,可是咱现在没办法,只能先这么认为),就是可以在里面传方法,就想传递引用参数一样。

其实委托最难懂的地方应该就是以前没接收过类似的概念,新概念的生成需要一段时间,就比如如果学过HTML,再学XML,就会对标签不那么陌生。委托一出来,感觉就怪怪的,将方法作为参数,以前很少这么用啊,(C++有,但是我菜鸟。大侠无视)。

基础的小例子在上面的博文里讲得很详细,可能有很多人开始和我一样,觉得书上讲的这些话,

定义委托的语法如下:

delegate IntMethodInvoker(int x);
在这个示例中,定义了一个委托,并指定该委托的每个实例都可以包含一个
方法的引用,该方法带有一个血参数,并返回voⅡ。理解委托的一个要点是它们的类型安全性非
常高。在定义委托时,必须给出它所表示的方法的签名和返回类型等全部细节。


就会觉的,天啊,这是什么啊。其实就是个名字而已,就好像有人告诉你有一只非洲猫鼬叫“Smelly Cat”,不管他,反正就是个名字,但是里面的参数一定要和你调用的方法的参数,或者说是函数签名一致哦。否则它不知道怎么处理。然后委托可以多播委托,就是一个委托干很多件事情,添加和删除是需要用“+=”和“-=”来处理,其实这里用到的不是很多,往后你们见到的都是事件和委托在一起的时候。那事件又是什么东西,事件就是触发之后处理,这个应该都接触过,但是事件的类型是什么,OK这里就是要用的到委托了。说的都混乱了。

看下面一个例子,我编写了一个老师点名的程序,通过在老师类里面的委托注册,可以知道学生的数目,然后点名的时候,注册的学生会答到。

首先是学生类,里面有一个方法来答到,委托是方法的指针,肯定要有一个方法作为委托的参数,就是它

public void Answer(string name)

很简单,就是看看叫道的是不是自己的名字,传入的name就是老师点的名字

	//如果名字相同,就喊“到”
        public void Answer(string name)
        {
            if (name.Equals(this.name))
            {
                Console.WriteLine("{0} say:I'm here!", name);
            }
        }

学生类完整代码

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

namespace DelegateTest
{
    class Student
    {
        private string name;

        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        public Student(string name)
        {
            this.name = name;
        }
	//如果名字相同,就喊“到”
        public void Answer(string name)
        {
            if (name.Equals(this.name))
            {
                Console.WriteLine("{0} say:I'm here!", name);
            }
        }
    }
}


接下来石老师了,老师很重要,首先需要定义一个委托,用来传递方法,

    public delegate void CallNameHander(string name);//declare delegate

因为它是方法的指针嘛,不能忘了,然后再顶一个事件,

public event CallNameHander CallNameEvent;//declare event
这个就是事件,你可能会觉得event 和CallNameEvent中间加的东西很眼熟,对了,就是刚刚的委托,为什么是它,我也不知道,但是就是这么规定的,你可以认为这是在告诉编译器事件是处理谁的委托的。

然后就是亲爱的点名函数了,当有人点名的时候,就会触发事件,CallEvent就不为空,然后就是事件处理了,调用了传进去的方法。

老师类完整代码
using System;

namespace DelegateTest
{
    public delegate void CallNameHander(string name);//declare delegate
    class Teacher
    {
        public event CallNameHander CallNameEvent;//declare event

        public void CallName(string name)
        {
            if (CallNameEvent != null)
            {
                CallNameEvent(name);
            }
        }
    }

}


最后来进行点名了,首先需要一个老师和几个学生,OK

            Teacher teacher = new Teacher();
            Student tom = new Student("tom");
            Student jack = new Student("jack");
            Student marry = new Student("marry");
他们来了。然后老师说来点名了,这时候有谁来了,大家就会答到,

            teacher.CallNameEvent += new CallNameHander(tom.Answer);
            teacher.CallNameEvent += new CallNameHander(jack.Answer);
            teacher.CallNameEvent += new CallNameHander(marry.Answer);

这几句的意思就是他们来到了课堂,而且已经注册了answet方法,就是知道自己要干什么----答到。

这时候恐怖的一幕发生了,老师拿起了点名册,然后恐吓超过多少次就取消成绩云云(大学生的痛),然后开始,

            teacher.CallName("tom");
这是调用了CallName,如果没记错,里面可是有个事件的,这里事件就是此奥用了,你要是问为什么,我也说不清,就是规定。然后就是以此达到

下一节课,杰克回家了饿,他就悲剧了。

点名测试

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

namespace DelegateTest
{
    class Test
    {
        static void Main(string[] args)
        {
            Teacher teacher = new Teacher();
            Student tom = new Student("tom");
            Student jack = new Student("jack");
            Student marry = new Student("marry");
            Console.WriteLine("---------------------------------");
            Console.WriteLine("Math Teacher say: Now Call Name!");
            teacher.CallNameEvent += new CallNameHander(tom.Answer);
            teacher.CallNameEvent += new CallNameHander(jack.Answer);
            teacher.CallNameEvent += new CallNameHander(marry.Answer);
            Console.WriteLine("Math Teacher say: tom!");
            teacher.CallName("tom");
            Console.WriteLine("Math Teacher say: jack!");
            teacher.CallName("jack");
            Console.WriteLine("Math Teacher say: marry!");
            teacher.CallName("marry");
            Console.WriteLine("---------------------------------");
            Console.WriteLine("then jack go home");
            Console.WriteLine("---------------------------------");
            teacher.CallNameEvent -= new CallNameHander(jack.Answer);
            Console.WriteLine("English Teacher say: Now Call Name!");
            Console.WriteLine("Math Teacher say: tom!");
            teacher.CallName("tom");
            Console.WriteLine("Math Teacher say: jack!");
            teacher.CallName("jack");
            Console.WriteLine("Math Teacher say: marry!");
            teacher.CallName("marry");
            Console.ReadKey();
        }

    }
}

运行结果



  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值