委托是一种引用方法的类型。一旦为委托分配了方法,委托将与该方法具有完全相同的行为。委托方法的使用可以像其他任何方法一样,具有参数和返回值。
如下面的示例所示:
public delegate int PerformCalculation(intx, int y);
1. 作为函数参数传递
我们以两个例子为例引出委托作为函数参数传递的好处。
首先来做一个例子,简单的计算器的例子。首先让这个计算器暂时只有两个功能加法和减法。所以写两个函数。
public static void Add(int a, int b)
{
Console.WriteLine(a+"+"+b+"="+(a+b));
}
public static void Minus(int a, int b)
{
Console.WriteLine(a + "-" + b + "="+( a - b));
}
再写一个函数来判断具体采用哪个函数是加法还是减法。
public static void Calculate(stringstrSign, int a, int b)
{
switch (strSign)
{
case "+":
Add(a, b);
break;
case "-":
Minus(a, b);
break;
}
}
我们在主函数中这样调用
static void Main(string[] args)
{
Calculate("+", 2, 6);
Calculate("-", 6, 2);
}
这样的话,就可以根据“+”和“-”来判断采用哪种算法。
上边的这个例子是不易于维护的,如果增加新的算法就得修改switch语句,这对于系统的可维护性是不利的。如果我们使用委托作为函数的参数传递的话,就会好恨多。
class Program
{
//定义委托,它定义了可以代表的方法的类型
public delegate void Calculate(int a,int b);
public static void Add(int a, int b)
{
Console.WriteLine(a + "+"+ b + "=" + (a + b));
}
public static void Minus(int a, int b)
{
Console.WriteLine(a + "-"+ b + "=" + (a - b));
}
//此方法使用Calculate类型的委托作为参数传递
public static voidPrintResult(Calculate action, int a, int b)
{
action(a, b);
}
static void Main(string[] args)
{
PrintResult (Add , 2, 6);
PrintResult (Minus , 6, 2);
}
}
在这个例子中,首先定义了一个委托,然后使用Calculate类型的委托作为参数传递。这样做的好处是,当想要添加另外一种计算的话,只需要添加一个计算的函数就好了,无需修改程序其他的地方。这就是委托作为函数参数传递的好处,使得程序的可维护性增强。
2. 委托之广播
委托对象的一个用途在于,可以使用 + 运算符将它们分配给一个要成为多路广播委托的委托实例。组合的委托可调用组成它的那两个委托。只有相同类型的委托才可以组合。
“-” 运算符可用来从组合的委托移除组件委托。
public delegate void Del(string strTest);
class Program
{
static void Main(string[] args)
{
MessageTest OK = new MessageTest();
Del d1 = new Del(OK.Message1);
Del d2=new Del (OK.Message2 );
Del d3 = new Del(OK.Message3);
Del d4 = new Del(OK.Message4);
Del dAll = d1 + d2 + d3 + d4;
dAll("代理广播");
dAll = dAll- d1;
dAll("代理之多路委托");
}
}
class MessageTest
{
public void Message1(string StrTest)
{
Console.WriteLine("使用Message1"+ StrTest);
}
public void Message2(string StrTest)
{
Console.WriteLine("使用Message2"+ StrTest);
}
public void Message3(string StrTest)
{
Console.WriteLine("使用Message3"+ StrTest);
}
public void Message4(string StrTest)
{
Console.WriteLine("使用Message4"+ StrTest);
}
}
运行结果
在这个例子中给委托绑定了一些方法,那么如何给委托绑定方法呢?
例如:
Del d1=new Del (OK.Message1 );
这样就给d1这个委托类型绑定了OK对象的一个Message1方法。
如果我们还要再给d1绑定一个方法就这样做:
d1+=OK.message2;
当然“-=”就是从绑定的方法中删除一个。
3. 匿名方法(来源于百度百科)
在 2.0 之前的 C# 版本中,声明委托的唯一方法是使用命名方法。C# 2.0 引入了匿名方法,而在 C# 3.0 及更高版本中,Lambda 表达式取代了匿名方法,作为编写内联代码的首选方式。
要将代码块传递为委托参数,创建匿名方法则是唯一的方法。
通过使用匿名方法,由于您不必创建单独的方法,因此减少了实例化委托所需的编码系统开销。
示例:
不使用匿名方法:
static voidMain(string[] args)
{
Thread thread = newThread(new ThreadStart(Run));
// 或 Threadthread = new Thread(Run); // c# 2.0 或以后版本支持
thread.Start();
}
static void Run()
{
// 要运行的代码 ...
}
使用匿名方法:
static voidMain(string[] args)
{
Thread thread = newThread(delegate()
{
// 要运行的代码
});
// 或 Threadthread = new Thread(new ThreadStart(delegate()
//{
// // 要运行的代码
//}));
thread.Start();
}
使用Lambda 表达式:
static voidMain(string[] args)
{
Thread thread = newThread(() =>
{
// 要运行的代码
});
// 或 Threadthread = new Thread(new ThreadStart(() =>
//{
// // 要运行的代码
//}));
thread.Start();
}