C#委托可以避免在程序中大量使用if-else语句,同时使程序具有更好的可扩展性。
1. C#委托的概述与声明
- 委托的概述
委托是一种引用类型,它表示对具有特定参数列表和返回类型的方法的引用。在实例化委托时,可以将其实例与任何具有兼容签名和返回类型的方法相关联,可以通过委托实例调用方法,也可以使用委托将方法作为参数传递给其他方法。
- 委托的声明
委托声明决定了可由该委托引用的方法,委托可指向一个与其具有相同标签的方法。委托的声明语法如下:
public delegate <return type> <delegate-name> <parameter list>
//<return type>表示返回类型
//<delegate-name>表示委托名
//<parameter list>表示参数列表
//例
public delegate void WatchDelegate();
2. 委托的使用
- 委托实例化
委托是一种特殊的类,使用委托与使用类相似,故使用new实例化委托。
WatchDelegate watch = new WatchDelegate(CallPartner);
//CallPartner()是通知的方法的引用
//在C#2.0的语法中,实例化委托可以简写为将方法引用直接指向委托,如下:
WatchDelegate watch = CallPartner;
- 调用委托
一般可以使用委托对象的Invoke()方法来调用委托。例如:
watch.Invoke();
//为了简化委托调用也可以简写为
watch();
注:指向的方法需要符合委托所定义的方法签名和返回类型。
- 多播委托
委托对象有一个好用的属性,就是可以用"+"运算符将多个对象分配到一个委托实例上,形成多播委托。多播委托包含了已经分配了的委托列表,因此多播委托被调用时会依次调用列表中的委托。但是多播委托仅可和合并类型相同的委托。也可使用”-“运算符从多播委托中删除组件委托。例如:
watch += new WatchDelegate(Escape);
- 使用委托将方法作为参数传递给另一个方法,例如:
首先定义一个类Human
public class Human
{
public delegate void HumanAction();
public void TakeAction(HumanAction humanAction)
{
humanAction.Invoke();
}
}
Program类里
static void Main(string[] args)
{
Human human = new Human() { };
human.TakeAction(Arrival);
}
/// <summary>
/// 人类的方法
/// </summary>
public static void Arrival()
{
Console.WriteLine("人类来了");
}
3. 一个简单的Demo
编写这样一个场景:有一群老鼠,在某地偷吃食物,其中有一只老鼠(Jerry)放哨,当发现猫(Tom)的时候需要通知其他老鼠逃跑,同时自己也要逃跑。代码如下:
public delegate void WatchDelegate();
class Program
{
static void Main(string[] args)
{
for (int i = 0; i < 100; i++)
{
bool b = false;
Random rd = new Random();
int x = rd.Next();
b = (x % 3 == 0);
WatchFunction(b);
if (b) break;
//线程
Thread.Sleep(2000);
}
}
/// <summary>
/// 观察的方法
/// </summary>
/// <param name="advent">是否到来</param>
public static void WatchFunction(bool advent)
{
if (advent)
{
WatchDelegate watch = new WatchDelegate(CallPartner);
watch += new WatchDelegate(Escape);
watch();
}
else
{
Console.WriteLine("没有发现异常");
}
}
/// <summary>
/// 通知的方法
/// </summary>
public static void CallPartner()
{
Console.WriteLine("小伙伴们,Tom来了,快跑");
}
/// <summary>
/// 逃跑的方法
/// </summary>
public static void Escape()
{
Console.WriteLine("Jerry正在向洞口跑去!");
}
}
效果图: