代碼環境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";
}
}
}
運行結果: