---------------------- Windows Phone 7手机开发、.Net培训、期待与您交流! ----------------------
委托只是一种特殊的类型,它包含的只是方法的地址;
假如在某个方法中需要另一个方法怎么办?委托就能帮我们解决这个问题,它可以作为某个方法的参数传入;
来看一下的例子及代码和注释:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace 委托delegate的进一步理解
{
class Program
{
static void Main(string[] args)
{
//注意实例化时的委托参数(也就是方法)不要带括号
ReturnValue r1 = new ReturnValue(ClassMethod.Method1); //实例化一个委托,使用静态方法做为参数
//ReturnValue r2 = ClassMethod.Method1; //其实这样写也是可以实例委托的,委托不就是方法的容器嘛
ReturnValue r3 = new ClassMethod().Method2; //也可以使用实例方法作为参数,都可以
ReturnValue r4 = delegate(double v)
{
return 2 * v;
}; //也可以使用匿名方法来实例委托
//我们把ClassMethod.Method1()方法传入ClassMethod.ShowValue方法中
ClassMethod.ShowValue(r1, 5.5);
//多播委托(委托链),上面介绍的委托都只包含一个方法,调用的次数与调用方法的次数相同;其实委托是可以
//包含多个方法的,但是一定要注意,包含多个方法的委托返回值为void,否则只能得到委托调用的最后一个
//方法的结果(可以使用运算符"+、-、+=、-=")
ReturnValue rr = r1 + r3;
//得到的只是最后一个方法的结果,而不是我们想要的两个结果,原因就是委托的返回值不为void
ClassMethod.ShowValue(rr, 2.5);
//要想得到多个方法的结果,我们因此要重新定义委托及方法,让它们都返回void
ReturnVoid r11 = ClassMethod.Method11;
ReturnVoid r22 = new ClassMethod().Method22;
ReturnVoid r33 = delegate(double value)
{
Console.WriteLine("传入的值为{0},结果为{1}", value, 2 * value);
};
ReturnVoid rs = r11 + r22 + r33;
ClassMethod.ShowValue1(rs, 10.5); //这样我们就可以都得到每个方法的结果了
/*但是多播委托有一个致命的问题,那就是如果前面方法有一个抛出异常,则整个迭代就停止;
解决的方法是使用delegate类的方法GetInvocationList(),它返回一个Delegate对象数组*/
ReturnVoid rE = ClassMethod.ThrowException;
ReturnVoid rsException = rE + rs;
//执行到第一个方法的时候就抛出异常,迭代也就停止了
//try
//{
// ClassMethod.ShowValue1(rsException, 1.5);
//}
//catch (Exception ee)
//{
// Console.WriteLine(ee.Message);
//}
//解决方法:
Delegate[] delegates = rsException.GetInvocationList();
//抛出异常后还是能够执行下去
foreach (ReturnVoid rvs in delegates)
{
try
{
ClassMethod.ShowValue1(rvs, 2.4);
}
catch(Exception ee)
{
Console.WriteLine(ee.Message);
}
}
Console.ReadKey();
}
}
//定义一个委托
delegate double ReturnValue(double d);
//重新定义返回void的委托
delegate void ReturnVoid(double d);
class ClassMethod
{
//静态方法
public static double Method1(double value)
{
value = value * 10;
return value;
}
public static void Method11(double value)
{
Console.WriteLine("传入的值为{0},结果为{1}",value,10 * value);
}
//我们在这里定义一个方法,并且抛出异常
public static void ThrowException(double b)
{
throw new Exception("抛出异常ThrowException方法");
}
//实例方法
public double Method2(double value)
{
value = value * value;
return value;
}
public void Method22(double value)
{
Console.WriteLine("传入的值为{0},结果为{1}",value,value * value);
}
//其实这里委托作为参数就是传入方法,以前我们的参数都是预定义类型及自己定义的类
public static void ShowValue(ReturnValue rv,double value)
{
double result = rv(value);
Console.WriteLine("传入的值为{0},结果为{1}", value, result);
}
public static void ShowValue1(ReturnVoid rv, double value)
{
rv(value);
}
}
}
---------------------- Windows Phone 7手机开发、.Net培训、期待与您交流! ----------------------