论文部分内容阅读
【摘要】本文介绍了Visual C#.NET中委托的基本概念、实例化、委托的调用,着重介绍了使委托来引用静态方法和非静态方法、将方法绑定到委托、取消对方法的绑定,以期能为实际开发带来具体参考价值。
【关键词】Visual C#.NET;.Net Framework;委托;绑定;方法
1.引言
委托在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易。它们就像是一道槛儿,过了这个槛的人,觉得真是太容易了。本文中,我将通过一个范例由浅入深地讲述什么是委托、委托的简单应用。
2.委托的概念及定义
.Net的MSDN关于委托的定义是:delegate 声明定义一种引用类型,该类型可用于将方法用特定的签名封装。委托实例封装静态方法或实例方法。委托大致类似于 C++ 中的函数指针;但是,委托是类型安全和可靠的。
Delegate实际上是一个abstract class(Delegate派生于System.MulticastDelegate, System.MulticastDelegate又派生于System.Delegate),所以可以在任何地方定义Delegate,可以在class类内部,也可以在类外部;还可以在命名空间中把委托定义为顶层对象。根据定义的可见性,可以在委托定义上添加一般的访问修饰符:public、 private和 protected等。
委托是可保存对方法的引用的类。与其他的类不同,委托类具有一个签名,并且它只能对与其签名匹配的方法进行引用。这样,委托就等效于一个类型安全函数指针或一个回调。虽然委托具有许多其他的用途,但这里只讨论委托实例封装静态方法或实例方法。一个委托声明足以定义一个委托类。声明提供委托的签名,公共语言运行库提供实现。
如何理解Delegate的类型安全特性?跟C++的函数指针相比。函数指针只不过是指向存储区的一个指针,无法说出这个指针实际指向什么东西,更别说想获取参数(parameter)和返回值(return value)之类的数据了。而delegate定义时必须指定它所代表的方法的所有细节,比如参数类型,个数以及返回值等等;C#中创建委托使用delegate关键字,委托名可以是任何你认为有意义的词。但必须使你的委托匹配你想指向的方法的签名。当C#的编译器处理委托类型时,会自动地生成一个密封(sealed)类。
3.委托的简单应用—可以封装静态方法也可以封装实例方法
我们先不管这个标题如何的绕口,也不管委托究竟是个什么东西,来看下面这个简单的例子:
using System;
namespace DelegateExample{
public delegate void ArithmeticDelegate(int x, int y); //声明委托
class DelegateClass{
//定义了可以被委托类型ArithmeticDelegate封装的Add实例方法,它和委托有相同签名
public void Add(int x, int y){
Console.WriteLine("Start Add:{0} +{1}={2}", x, y, x + y);
}
//可以被委托类型ArithmeticDelegate封装的Sub静态方法,它和委托有相同签名
public static void Sub(int x, int y){
Console.WriteLine("Start Sub:{0}-{1}={2}", x, y, x - y);
}
static void Main(string[] args){
DelegateClass objTest = new DelegateClass();
//委托实例化,并指明其封装的实例方法Add。
ArithmeticDelegate delegateAdd = new ArithmeticDelegate(objTest.Add);
delegateAdd(2, 3);//委托的调用,实质上运行的是Add(2,3)方法
//委托实例化,并指明其封装的静态方法Sub。
ArithmeticDelegate delegateSub = new ArithmeticDelegate(DelegateClass.Sub);
delegateSub(2, 3); //委托的调用, 实质上运行的是Sub(2,3)方法
ArithmeticDelegate d1 = null;
//给此委托变量d1先后绑定Add方法和Sub方法
d1 += delegateAdd;
d1 += delegateSub;
d1(22, 33);
//取消对Sub方法的绑定
d1 -= delegateSub;
d1(222, 333);
}
}
}
输出结果如下:
Start Add:2 +3=5
Start Sub:2-3=-1
Start Add:22 +33=55
Start Sub:22-33=-11
Start Add:222 +333=555
代码分析:
【1】、声明委托
声明委托的格式:
<修饰符号> delegate(argument list)
如:public delegate void ArithmeticDelegate(int x, int y);
声明一个新的委托类型。每个委托类型都描述参数的数目和类型,以及它可以封装的方法的返回值类型。每当需要一组新的参数类型或新的返回值类型时,都必须声明一个新的委托类型。
【2】、实例化委托
声明了委托类型后,必须创建委托对象并使之与特定方法关联。与所有其他对象类似,新的委托对象用 new 表达式创建。但创建委托时,传递给 new 表达式的参数很特殊:它的编写类似于方法调用,但没有方法的参数。
如:
ArithmeticDelegate delegateSub = new ArithmeticDelegate(DelegateClass.Sub);
创建与静态方法Sub关联的新的委托对象。
又如:ArithmeticDelegate delegateAdd = new ArithmeticDelegate(objTest.Add);;
创建与对象DelegateClass.objTest 上的非静态方法Add关联的新的委托对象。请注意一旦创建了委托,它所关联到的方法便永不改变:委托对象不可改变。
【3】、调用委托
创建委托对象后,通常将委托对象传递给将调用该委托的其他代码。通过委托对象的名称(后面跟着要传递给委托的参数,括在括号内)调用委托对象。
如delegateAdd(2, 3),实质上运行的是Add(2,3)方法
【4】将方法绑定到委托
使用委托可以将多个方法绑定到同一个委托变量,当调用此变量时(这里用“调用”这个词,是因为此变量代表一个方法),可以依次调用所有绑定的方法。
如:ArithmeticDelegate d1 = null;
d1 += delegateAdd;
d1 += delegateSub;
d1(22, 33);
委托变量d1先后绑定Add方法和Sub方法,在运行d1(22, 33)时,其实相当于,先后运行Add(22,33),Sub(22,33);
【5】取消对方法的绑定
既然给委托可以绑定一个方法,语法是+=那么也应该有办法取消对方法的绑定,很容易想到,这个语法是“-=”:
如:ArithmeticDelegate d1 = null;
d1 += delegateAdd;
d1 += delegateSub;
d1 -= delegateSub;
此时的委托变量d1其实只封装了Add方法了。
我们现在对委托做一个总结:委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法,可以避免在程序中大量使用If-Else(Switch)语句,同时使得程序具有更好的可扩展性。
委托应用的步骤:先声明委托,再实例化并指明所代具体方法,然后再调用委托。
4.结束语
本文首先引用委托的概念,然后通过一个小程序向大家介绍委托的声明、委托的实例化、委托的调用及委托的绑定和取消委托的绑定。最后总结委托的应用步骤。
【参考文献】
[1]谢云著.Visual C# 2005程序设计基础与实例教程.研究出版社,2008.2.
[2]里克特 著.Microsoft .NET 框架程序设计(修订版)[M].李建忠.北京:清华大学出版社,2003.11.
[3]Microsoft著.C#程序设计语言.高等教育出版社.2003.8
作者简介:朱小兵(1978--),男,本科,计算机专业,老师
【责任编辑:王利强】
【关键词】Visual C#.NET;.Net Framework;委托;绑定;方法
1.引言
委托在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易。它们就像是一道槛儿,过了这个槛的人,觉得真是太容易了。本文中,我将通过一个范例由浅入深地讲述什么是委托、委托的简单应用。
2.委托的概念及定义
.Net的MSDN关于委托的定义是:delegate 声明定义一种引用类型,该类型可用于将方法用特定的签名封装。委托实例封装静态方法或实例方法。委托大致类似于 C++ 中的函数指针;但是,委托是类型安全和可靠的。
Delegate实际上是一个abstract class(Delegate派生于System.MulticastDelegate, System.MulticastDelegate又派生于System.Delegate),所以可以在任何地方定义Delegate,可以在class类内部,也可以在类外部;还可以在命名空间中把委托定义为顶层对象。根据定义的可见性,可以在委托定义上添加一般的访问修饰符:public、 private和 protected等。
委托是可保存对方法的引用的类。与其他的类不同,委托类具有一个签名,并且它只能对与其签名匹配的方法进行引用。这样,委托就等效于一个类型安全函数指针或一个回调。虽然委托具有许多其他的用途,但这里只讨论委托实例封装静态方法或实例方法。一个委托声明足以定义一个委托类。声明提供委托的签名,公共语言运行库提供实现。
如何理解Delegate的类型安全特性?跟C++的函数指针相比。函数指针只不过是指向存储区的一个指针,无法说出这个指针实际指向什么东西,更别说想获取参数(parameter)和返回值(return value)之类的数据了。而delegate定义时必须指定它所代表的方法的所有细节,比如参数类型,个数以及返回值等等;C#中创建委托使用delegate关键字,委托名可以是任何你认为有意义的词。但必须使你的委托匹配你想指向的方法的签名。当C#的编译器处理委托类型时,会自动地生成一个密封(sealed)类。
3.委托的简单应用—可以封装静态方法也可以封装实例方法
我们先不管这个标题如何的绕口,也不管委托究竟是个什么东西,来看下面这个简单的例子:
using System;
namespace DelegateExample{
public delegate void ArithmeticDelegate(int x, int y); //声明委托
class DelegateClass{
//定义了可以被委托类型ArithmeticDelegate封装的Add实例方法,它和委托有相同签名
public void Add(int x, int y){
Console.WriteLine("Start Add:{0} +{1}={2}", x, y, x + y);
}
//可以被委托类型ArithmeticDelegate封装的Sub静态方法,它和委托有相同签名
public static void Sub(int x, int y){
Console.WriteLine("Start Sub:{0}-{1}={2}", x, y, x - y);
}
static void Main(string[] args){
DelegateClass objTest = new DelegateClass();
//委托实例化,并指明其封装的实例方法Add。
ArithmeticDelegate delegateAdd = new ArithmeticDelegate(objTest.Add);
delegateAdd(2, 3);//委托的调用,实质上运行的是Add(2,3)方法
//委托实例化,并指明其封装的静态方法Sub。
ArithmeticDelegate delegateSub = new ArithmeticDelegate(DelegateClass.Sub);
delegateSub(2, 3); //委托的调用, 实质上运行的是Sub(2,3)方法
ArithmeticDelegate d1 = null;
//给此委托变量d1先后绑定Add方法和Sub方法
d1 += delegateAdd;
d1 += delegateSub;
d1(22, 33);
//取消对Sub方法的绑定
d1 -= delegateSub;
d1(222, 333);
}
}
}
输出结果如下:
Start Add:2 +3=5
Start Sub:2-3=-1
Start Add:22 +33=55
Start Sub:22-33=-11
Start Add:222 +333=555
代码分析:
【1】、声明委托
声明委托的格式:
<修饰符号> delegate
如:public delegate void ArithmeticDelegate(int x, int y);
声明一个新的委托类型。每个委托类型都描述参数的数目和类型,以及它可以封装的方法的返回值类型。每当需要一组新的参数类型或新的返回值类型时,都必须声明一个新的委托类型。
【2】、实例化委托
声明了委托类型后,必须创建委托对象并使之与特定方法关联。与所有其他对象类似,新的委托对象用 new 表达式创建。但创建委托时,传递给 new 表达式的参数很特殊:它的编写类似于方法调用,但没有方法的参数。
如:
ArithmeticDelegate delegateSub = new ArithmeticDelegate(DelegateClass.Sub);
创建与静态方法Sub关联的新的委托对象。
又如:ArithmeticDelegate delegateAdd = new ArithmeticDelegate(objTest.Add);;
创建与对象DelegateClass.objTest 上的非静态方法Add关联的新的委托对象。请注意一旦创建了委托,它所关联到的方法便永不改变:委托对象不可改变。
【3】、调用委托
创建委托对象后,通常将委托对象传递给将调用该委托的其他代码。通过委托对象的名称(后面跟着要传递给委托的参数,括在括号内)调用委托对象。
如delegateAdd(2, 3),实质上运行的是Add(2,3)方法
【4】将方法绑定到委托
使用委托可以将多个方法绑定到同一个委托变量,当调用此变量时(这里用“调用”这个词,是因为此变量代表一个方法),可以依次调用所有绑定的方法。
如:ArithmeticDelegate d1 = null;
d1 += delegateAdd;
d1 += delegateSub;
d1(22, 33);
委托变量d1先后绑定Add方法和Sub方法,在运行d1(22, 33)时,其实相当于,先后运行Add(22,33),Sub(22,33);
【5】取消对方法的绑定
既然给委托可以绑定一个方法,语法是+=那么也应该有办法取消对方法的绑定,很容易想到,这个语法是“-=”:
如:ArithmeticDelegate d1 = null;
d1 += delegateAdd;
d1 += delegateSub;
d1 -= delegateSub;
此时的委托变量d1其实只封装了Add方法了。
我们现在对委托做一个总结:委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法,可以避免在程序中大量使用If-Else(Switch)语句,同时使得程序具有更好的可扩展性。
委托应用的步骤:先声明委托,再实例化并指明所代具体方法,然后再调用委托。
4.结束语
本文首先引用委托的概念,然后通过一个小程序向大家介绍委托的声明、委托的实例化、委托的调用及委托的绑定和取消委托的绑定。最后总结委托的应用步骤。
【参考文献】
[1]谢云著.Visual C# 2005程序设计基础与实例教程.研究出版社,2008.2.
[2]里克特 著.Microsoft .NET 框架程序设计(修订版)[M].李建忠.北京:清华大学出版社,2003.11.
[3]Microsoft著.C#程序设计语言.高等教育出版社.2003.8
作者简介:朱小兵(1978--),男,本科,计算机专业,老师
【责任编辑:王利强】