C#委托详解
来源:互联网 发布:mastercam铣螺纹编程 编辑:程序博客网 时间:2024/05/21 09:07
C#中的委托类似C、C++中的函数指针。使用委托,程序员可以将方法引用封装在委托对象类。然后可以将该委托对象传递给可调用所引用方法的代码,而不必再编译时知道将调用哪个方法。委托时一种引用方法的类型,一旦为委托分配了方法,委托将与该方法具有完全相同的行为。委托时定义回调方法的理想选择。
与c和c++的函数指针不同,委托时面向对象、类型安全的。
1、委托的声明
两个步骤:
首先定义要使用的委托,即告诉编译器这种类型的委托代表了哪种类型的方法。
然后创建该委托的一个或多个实例。
其定义语法为: delegate void IntMethodInvoker(int a);
上面这句话表明,定义了一个委托IntMethodInvoker,并指定该委托的每个实例都包含一个方法细节,该方法带有一个int参数,并且返回值为void
实际上定义一个委托就是定义一个”新类“。它可以定义在任何地方。
2、委托的使用
例子如下:
private delegate string GetString();//此处定义一个没有参数,且返回值为string的委托 static void Main(string[] args) { int x = 23; //GetString firstString = new GetString(x.ToString); //上一句也等价于下一句,但是注意不能写成GetString firstString = x.ToString(); GetString firstString = x.ToString;//这为委托推断 Console.WriteLine("String is {0}", firstString()); //上一句中firstString()等价于x.ToString()方法 Console.ReadLine(); }
注意:不能调用x.ToString()方法把它传递给委托变量,因为调用该方法返回的事一个能赋予委托变量的字符串对象,只能该方法的地址赋予委托变量。
3、委托示例
class test { public static double MultiplyByTwo(double value) { return value * 2; } public static double Square(double value) { return value * value; } } delegate double DoubleOperation(double x); class Program { static void Main(string[] args) { DoubleOperation[] operations = { test.MultiplyByTwo, test.Square }; for (int i = 0; i < operations.Length;i++ ) { Console.WriteLine("Using operations[{0}]:", i); display(operations[i], 2.0); display(operations[i], 7.94); display(operations[i], 1.233); Console.WriteLine(); } Console.ReadLine(); } static void display(DoubleOperation action, double value) { double result = action(value); Console.WriteLine("Value is {0},result of operation is{1}", value, result); } }
输出结果为:
这段代码实例化了一个委托数组,并用两个函数签名符合的函数填充了该数组(就好比实例化类一样),然后分别取出这委托的这两个实例将其传递给另一个方法调用。
operations[i]表示这个委托,即这个委托代表的方法
operations[i](2.23)表示调用这个方法,参数放在括号中。
4、多播委托
多播委托允许把多个方法调用链接起来,成为一个列表。然后依次调用,一般委托的签名必须返回为void,不然就只能得到委托调用的最后一个方法的结果了。多播委托可以识别+、+=,-、-=等运算符。
多播委托示例如下:
class test { public static void one(double value) { double result = value * 2; Console.WriteLine("One : the value is {0}, give you {1},",value,result); } public static void two(double value) { double result = value * value; Console.WriteLine("Two : the value is {0}, give you {1},", value, result); } } delegate void DoubleOperation(double value);//定义委托 class Program { static void Main(string[] args) { DoubleOperation opreations = test.one;//实例化委托 opreations += test.two; display(opreations, 2.0); display(opreations, 7.94); display(opreations, 1.233); Console.ReadLine(); } static void display(DoubleOperation action, double value) { Console.WriteLine(); action(value);//该语句会按顺序调用action委托实例中的方法。 } }
输出结果为:
使用多播委托应注意:
对同一个委托调用方法链的顺序并未正式定义,因此应避免编写依赖于以特定顺序调用方法的代码。
多播委托包含一个逐个调用的委托集合,如果通过委托调用的一个方法抛出异常,则整个迭代就会停止。即只执行了异常前的方法,停止在抛异常的方法那儿,之后的方法不再执行。
解决这个方法我们可以将委托链利用Delegate类定义的方法GetInvocationList()方法将其转换为Delegate对象数组,并循环一次执行相关方法,捕捉异常后,可继续下一次迭代。
如:
static void main(){ DemoDelegate dl = one; dl+=two; Delegate[] delegates=dl.GetInvocationList(); foreach(DemoDelegate d in delegates) { try { d(); } catch(Exception) { Console.WriteLine("Exception caught"); } }}
5、匿名委托
定义匿名委托时与前面相同,实例化时则不是传送已知的方法名,而是使用一个简单的代码块,它前面的关键字为delegate,后面括号中跟参数,大括号中跟实现代码。即:delegateName test = delegate(string param){代码};//delegareName为定义的委托,test为该委托的实例
使用匿名方法应注意:
- 匿名方法不能使用跳转语句跳到该匿名方法的外部,也不能从外部跳到匿名方法的内部。
- 在匿名方法中不能访问不安全的代码。
- 不能访问在匿名方法外部使用的ref和out参数化,当可以访问外部定义的其他变量
- 若要多次编写同一个功能的的方法,就不要用匿名方法。
- c#中的委托详解
- C#委托详解
- C# 委托详解(一)
- C#委托使用详解
- C# 委托详解汇总
- C#委托和事件详解
- C#委托、自定义事件详解
- C#委托和事件详解
- C#委托与事件详解
- C#实践与委托详解
- c#委托与事件(详解
- C#事件与委托详解
- C#事件与委托详解
- C#委托和事件详解
- C#事件与委托详解
- C#事件与委托详解
- C#事件与委托详解
- C# 事件与委托详解
- 使用jQuery和CSS将背景图片拉伸
- 单例模式
- git版本控制使用入门
- java设计模式6:Adapter
- uva 10318 - Security Panel
- C#委托详解
- 千与千寻django(五)---django的自带管理界面
- 原型制作
- 高手真经 13条Java核心技术
- 虚拟机中linux无法访问外网
- C++ 标准头文件与C头文件区别与联系
- PHP包含或读取了哪个配置文件的跟踪探讨。
- TCP/IP_Socket编程 - 基本套接字
- C语言函数调运栈及开销