委托和事件在.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);
}
}
好了,希望能对你有所帮助.