理解委托(delegate)及为什么要使用委托
委托:是一种定义方法签名的类型。 当实例化委托时,您可以将其实例与任何具有兼容签名的方法相关联。 您可以通过委托实例调用方法。
上述为官方说法,理解起来比较难,举个生活中的例子:
某人有三子,让他们各自带一样东西出门,并带回一头猎物。
上面一句话可以理解为父亲对儿子的委托:猎物 办法(工具 某工具)-->delegate 猎物(返回值) 带回猎物(委托名)(工具(参数类型) x)-->delegate int GetValue(int i)
三个人执行委托的方法各不相同
兔子 打猎(工具 弓)-public static int GetValue1(int i){ return i; }
野鸡 买(工具 钱)-public static int GetValue2(int i){ return i*2; }
狼 诱捕(工具 陷阱)-public static int GetValue3(int i){ return i*i; }
如何调用委托
用new关键字(将方法名作为参数)生成一个委托对象,建立委托与方法的关联。
GetValue obj = new GetVlaue(Class.GetValue1);
obj(3); --> result: 3
GetValue obj = new GetVlaue(Class.GetValue2);
obj(3); --> result: 6
GetValue obj = new GetVlaue(Class.GetValue3)
obj(3); --> result: 9
通过委托调用不同的方法,将需要执行的方法作为委托的参数
我们还可以实现多路广播委托,什么是多路广播委托,看例子:
GetValue obj = new GetVlaue(Class.GetValue1);
obj += new GetVlaue(Class.GetValue2);
obj += new GetVlaue(Class.GetValue3);
obj(3);
多路广播委托即:一处调用委托,所有关联方法都会被调用。
委托的好处
1.相当于用方法作为另一方法参数(类似于C的函数指针)
2.在两个不能直接调用的方法中作为桥梁,如:在多线程中的跨线程的方法调用就得用委托
3.当不知道方法具体实现什么时使用委托,如:事件中使用委托
附:.net framework中对委托进行了封装,直接使用Func<>来代替delegate,Func<>最多有四个参数的重载。
NEW:
我把委托理解为:委托是一种方法的格式,当然他也是一种类型。
只要是方法的格式跟委托定义的格式是一样的,那么就可以把该方法附加给该委托。看以下demo
声明委托:
public delegate void Add(int a,int b );
声明一个格式相同的方法:
static void OtherMethod(int a ,int b)
{Console.WriteLine(a+b);}
给类声明一个委托类型的成员变量
public class Person
{
public string Name { set; get; }
public string Age { set; get; }
public Add MyAdd ;
}
将方法附加给委托,调用,测试如下:
static voidMain(string[] args)
{
Person p1 =new Person ();
p1.MyAdd = OtherMethod;
p1.MyAdd(7, 8);
Console.ReadLine();
}
控制台输出—— 15
如果我们定义的OtherMethod不常用,就没有必要单独声明一个方法。可以用匿名方法,即:在给委托附加方法的时候,直接构造一个跟委托格式相同的匿名方法就可以了:
写法如下:
p1.MyAdd = delegate(inta, int b) { Console.WriteLine(a + b); };
匿名方法,顾名思义,没有方法名,只有方法参数和方法的算法,可真是够简单了。
同样我们也可以直接用lamuda表达式,直接构造一个方法,如下:
p1.MyAdd = (int a, int b) => {Console.WriteLine(a + b); };
匿名方法和拉姆达表达式的出现,使得写方法变得更加简便了。