代码环境Visual Studio 2010 .NET v4.0.30319
代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace delegateTest
{
public delegate void DelegateFirst();//委托类型可以声明在此处,也可以在类或结构中声明
class Program
{
//1、通过delegate关键字声明的委托是一个类型,其声明位置可以在名字空间内,也可以在类或结构中,有别于事件(事件event声明的是类或结构的成员)
//2、Delegate、MulticastDelegate、delegate是有区别的:
// Delegate和MulticastDelegate都是抽象类,delegate是一个C#关键词;
// Delegate是委托的抽象基类,MulticastDelegate继承自Delegate,所有用delegate声明的委托都继承自MulticastDelegate;
//3、声明委托的时候需要声明其名字、所指向方法的返回类型和参数(包括out和ref参数)
//4、委托是面向对象和类型安全的
//5、委托可以指向静态方法、实例方法、匿名方法或Lambda方法
//6、委托可以指向一个或多个方法
//7、委托可以采用异步调用(在后台线程中调用,但必须是指向一个方法)也可以采用同步调用的方法
//8、委托可以通过+=和-=两个运算符增加或移除方法
public delegate void DelegateSecond(string msg);//DelegateSecond指向包含一个string参数,无返回值的方法
public delegate string DelegateThird();
static void Main(string[] args)
{
//定义委托变量
DelegateSecond second;
DelegateThird third;
//初始化委托变量,可以有多种方式
//1、通过“委托名(方法名)”初始化
//2、通过方法名初始化
second = new DelegateSecond(Method1);//方式一,此处指向的是静态方法
third = Method3;//方式二
//调用委托变量所指向的方法,有多种方式,在调用之前必须确保委托有相应的指向方法,若没有则出错
//1、通过“委托变量名(参数列表)”同步调用
//2、通过Invoke同步调用
//3、通过遍历其中的方法进行逐个调用
//4、通过begininvoke进行异步调用,只能指向一个方法
if (second != null)//在类型调用前需要判断second中是否有指向的方法
{
second("1、通过委托变量名(参数列表)进行同步调用");//方式一
second.Invoke("2、通过Invoke惊醒同步调用");//方式二
foreach (Delegate dele in second.GetInvocationList())//方式三
{
dele.DynamicInvoke("3、通过遍历其中的方法进行逐个调用");
}
IAsyncResult ar= second.BeginInvoke("4、通过BeginInvoke进行异步调用", null, null);//方式四
second.EndInvoke(ar);
}
//可以通过+=增加指向的方法,增加的方式有多种
//1、增加静态方法,之前展示的就是这种方式
//2、增加实例方法
//3、增加匿名方法
//4、增加Lambda方法
Program p = new Program();//方式二
second += p.Method2;
second += delegate(string msg)
{
Console.WriteLine("*****匿名方法******");
Console.WriteLine("msg:" + msg);
Console.WriteLine("ThreadManagedId:" + Thread.CurrentThread.ManagedThreadId);
Console.WriteLine("*****匿名方法******");
};//方式三
second += (string msg) =>
{
Console.WriteLine("*****Lambda方法******");
Console.WriteLine("msg:" + msg);
Console.WriteLine("ThreadManagedId:" + Thread.CurrentThread.ManagedThreadId);
Console.WriteLine("*****Lambda方法******");
};//方式四
//通过委托依次调用四个方法
Console.WriteLine("");
Console.WriteLine("通过委托依次调用四个方法");
if(second!=null) second("可以调用四个方法");
//通过-=移除其中的方法,只能移除具名方法,不能移除匿名和Lambda方法
second -= p.Method2;
Console.WriteLine("");
Console.WriteLine("移除一个方法后的调用结果");
if(second!=null) second("移除其中一个方法Method2");
//若有返回类型的委托中有多个方法,则调用之后只会返回最后一个方法的返回值
Console.WriteLine("");
third += Method4;
if(third!=null) Console.WriteLine("third调用的返回值为:" + third());
}
//定义一个静态方法
public static void Method1(string msg)
{
Console.WriteLine("*****Method1******");
Console.WriteLine("msg:" + msg);
Console.WriteLine("ThreadManagedId:" + Thread.CurrentThread.ManagedThreadId);
Console.WriteLine("*****Method1******");
}
//定义一个实例方法
public void Method2(string msg)
{
Console.WriteLine("*****Method2******");
Console.WriteLine("msg:" + msg);
Console.WriteLine("ThreadManagedId:" + Thread.CurrentThread.ManagedThreadId);
Console.WriteLine("*****Method2******");
}
public static string Method3()
{
Console.WriteLine("这是Method3!");
return "Method3";
}
public static string Method4()
{
Console.WriteLine("这是Method4!");
return "Method4";
}
}
}
运行结果: