委託是對函數的封裝,可以當做給方法的特徵指定一個名稱。它本質上就是變相的型別安全的指標。
假想情境:01國際電腦語言大會上,各種電腦語言匯聚一堂,共同探討電腦語言的發展趨勢和優勢。由於語言眾多,主辦方pc和mac決定給每位參會者10分鐘發言機會。Code is cheap。看看它們都怎麼說:
類圖:
代碼如下:Code
using System;
using System.Collections.Generic;
using System.Text;
namespace CsStudy
{
class DelegateStudy
{
interface IProgramLanguage
{
void Speak();
}
class Java : IProgramLanguage
{
public void Speak()
{
Console.WriteLine("Java is the best.");
}
}
class JavaScript : IProgramLanguage
{
public void Speak()
{
Console.WriteLine("JavaScript is the best.");
}
}
class C : IProgramLanguage
{
public void Speak()
{
Console.WriteLine("C is the best.");
}
}
class CSharp : IProgramLanguage
{
public void Speak()
{
Console.WriteLine("Oh really? C# is the best of best.");
}
}
public delegate void LanguageSpeak(); //聲明委託
LanguageSpeak programLs;
public void BeginSpeak()
{
Console.WriteLine("Are you ready? Go!");
if (programLs != null)
{
programLs();
}
}
/// <summary>
/// 用戶端調用
/// </summary>
static void Main(string[] args)
{
DelegateStudy ds = new DelegateStudy();
ds.programLs += new DelegateStudy.LanguageSpeak(new Java().Speak);
ds.programLs += new DelegateStudy.LanguageSpeak(new JavaScript().Speak);
ds.programLs += new DelegateStudy.LanguageSpeak(new C().Speak);
ds.programLs += new DelegateStudy.LanguageSpeak(new CSharp().Speak);
ds.BeginSpeak();
Console.Read();
}
}
}
委託總結:
(1)與命名方法關聯時委託在文法上總是帶有一個參數的建構函式,這個參數就是委託引用的方法,這個方法必須匹配最初定義委託時的簽名,即方法傳回值類型和參數序列必須都相匹配。
(2)通過將委託與命名方法(靜態或執行個體)或匿名方法關聯,可以執行個體化委託。委託的執行個體仍稱為委託。
(3)使用委託即通過委託的執行個體調用委託引用的方法,委託的執行個體名後面的括弧包含的參數與委託引用的方法參數匹配。
(4)委託可以包含多個方法,這種委託稱為多播委託。多播委託只能引用傳回值為void的方法。運算子有+、+=、-、-=,用來增加方法和刪除方法。
(5)委託使用三步曲:定義->關聯->調用
Code
public delegate void LanguageSpeak(); //定義
LanguageSpeak programLs = new LanguageSpeak(new CSharp().Speak); //關聯
programLs(); //調用
最後來一個帶參數的委託調用:Code
using System;
using System.Collections.Generic;
using System.Text;
namespace CsStudy
{
using System;
class DelegateStudy
{
interface IProgramLanguage
{
string Speak(string language);
}
class Java : IProgramLanguage
{
public string Speak(string language)
{
return string.Format( "{0} is the best.",language);
}
}
class JavaScript : IProgramLanguage
{
public string Speak(string language)
{
return string.Format("{0} is the best.", language);
}
}
class C : IProgramLanguage
{
public string Speak(string language)
{
return string.Format("{0} is the best.", language);
}
}
class CSharp : IProgramLanguage
{
public string Speak(string language)
{
return string.Format("{0} is the best.", language);
}
}
public delegate string LanguageSpeak(string language); //聲明委託
LanguageSpeak programLs;
/// <summary>
/// 用戶端調用
/// </summary>
static void Main(string[] args)
{
DelegateStudy ds = new DelegateStudy();
ds.programLs = new DelegateStudy.LanguageSpeak(new Java().Speak);
Console.WriteLine(ds.programLs("Java"));
ds.programLs += new DelegateStudy.LanguageSpeak(new JavaScript().Speak);
Console.WriteLine(ds.programLs("JavaScript"));
ds.programLs += new DelegateStudy.LanguageSpeak(new C().Speak);
Console.WriteLine(ds.programLs("C"));
ds.programLs += new DelegateStudy.LanguageSpeak(new CSharp().Speak);
Console.WriteLine(ds.programLs("C#"));
Console.Read();
}
}
}