详细从浅到深讲解委托和事件

来源:互联网 发布:淘宝保证金 编辑:程序博客网 时间:2024/09/21 09:25


 委托和事件在.net中的应用非常广泛,但是很多人都不太了解为什么使用委托?委托的应用有什么优点?接下来就为大家从什么是委托,委托的实现,为什么要使用委托,三个部分进行由浅到深的讲解,存在问题的地方,还请大家指正

 

1.什么是委托?

 从语言的角度来讲,委托就是把事情托付给别人或别的机构办理.

 请看下面一段代码:

public class example:Page{    protected void Page_Load(object sender, EventArgs e)    {        showInfo del = FunShowInfo;//委托和随string等类型一样,可以定义一种参数类型        Response.Write(del(6).ToString());    }    public delegate int showInfo(int i);    public int FunShowInfo(int info)    {        return info;    }}

运行结果: 在页面上显示 6


这个例子中,我们把FunShowInfo委托给del,当执行del的时候实现FunShowInfo的运行结果;

说道这里,大家应该对委托有了一定的认识,那么在C#中委托是什么类型呢?

委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递.

委托可以定义在类的内部或外部,因为委托本身就是类,所以类可以定义在哪委托就可以定义在哪。

委托和string等类型一样,可以定义一种参数类型,然后把方法赋值给委托;不同于string的是,他可以接受多个方法的委托,然后调用委托的时候可以调用多个方法;在后面的讲解中会讲道;

 

2.委托的实现

通俗的可以用下面地话描述:

         1.定义一个委托,用关键字delegate ,具有与事件相同的返回值和参数;

         2.声明一个委托,并把事件传给它;

         3.把委托作为参数传递,调用;

 

3.为什么使用委托

看完上面的例子,大家可能会疑问,我直接可以写成下面的代码:

public class example : Page{    protected void Page_Load(object sender, EventArgs e)    {       Response.Write(FunShowInfo(4));    }    public int FunShowInfo(int info)    {        return info;    }}

会实现一样的效果,用委托实现还多写了几行代码;它的意义何在呢?

好,那么请看下面的例子:

public class example : Page    {        protected void Page_Load(object sender, EventArgs e)        {            Hello(langurage.English, "Demi");        }        public enum langurage        {            Chinese, English        }        public void EnglishGreeting(string name)        {            Response.Write("Morning" + "\r\n" + name);        }        public void ChineseGreeting(string name)        {            Response.Write("你好" + "\r\n" + name);        }        public void Hello(langurage lan, string name)        {            switch (lan)            {                case langurage.English:                    EnglishGreeting(name);                    break;                case langurage.Chinese:                    ChineseGreeting(name);                    break;            }        }    }

这个代码实现的是.当页面加载的时候,会根据传入的枚举类型和string类型的参数,执行不同的问候方法;但是这个方案的可扩展性很差,如果日后我们需要再添加韩文、日文问候方法,就不得不反复修改枚举和Hello() Case方法,以适应新的需求。

思考:

我们来看Hello这个方法:

Hello(langurage lan, string name)

它接受一个string类型的name参数.然后根据传入的langurage 类型参数lan来switch case判断执行的方法体;试想一下,如果我们传入的参数不通过switch case判断,只是根据参数本身就可以知道执行的方法体,那么岂不是省去了switch case语句,模型如下:

Hello(string name,***LangurageGreeting)

{

LangurageGreeting(name);

}

那怎么实现呢?这里就需要用到委托了----------------请看代码--------------:

 

    public class example : Page    {        protected void Page_Load(object sender, EventArgs e)        {            Hello("Demi", EnglishGreeting);            Hello("杨幂", ChineseGreeting);        }        public delegate void LangurageGreeting(string name);        private void EnglishGreeting(string name)        {            Response.Write("Morning, " + name + "<br/><br/>");        }        private void ChineseGreeting(string name)        {            Response.Write("早上好, " + name);        }        //注意此方法,它接受一个GreetingDelegate类型的方法作为参数        private static void Hello(string name, LangurageGreeting MakeGreeting)        {            MakeGreeting(name);        }    }

总结: 委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递.以避免在程序中大量使用If-Else(Switch)语句,同时使得程序具有更好的可扩展性。

委托是一个引用类型,它具有引用类型所具有的通性.引用类型保存的不是实际值,而是保存对存储在托管堆中的对象的引用.委托保存的是对函数(方法)的引用.

 

在刚开始的时候我们说过,委托和 类型 string 的地位一样,都是定义了一种参数类型,那么,我是不是也可以这么使用委托?

 public class example : Page    {        protected void Page_Load(object sender, EventArgs e)        {            LangurageGreeting english = EnglishGreeting;            LangurageGreeting chinese = ChineseGreeting;            //这里我们可以给此委托变量再绑定一个方法            //english += ChineseGreeting;              //给此委托变量取消取消一个方法            //english -= ChineseGreeting;             //需要注意一点是,第一次用的“=”,是赋值的语法;第二次,用的是“+=”,是绑定的语法。如果第一次就//使用“+=”,将出现“使用了未赋值的局部变量”的编译错误。                      Hello("Demi", english);             Hello("杨幂", chinese);        }        public delegate void LangurageGreeting(string name);        private void EnglishGreeting(string name)        {            Response.Write("Morning, " + name + "<br/><br/>");        }        private void ChineseGreeting(string name)        {            Response.Write("早上好, " + name);        }        //注意此方法,它接受一个GreetingDelegate类型的方法作为参数        private static void Hello(string name, LangurageGreeting MakeGreeting)        {             MakeGreeting(name);         }    }


 好了,希望能对你有所帮助.

 

 

 

原创粉丝点击