先看看委託的概述:編程
•委託相似於 C++ 函數指針,但它們是類型安全的。windows
• 委託容許將方法做爲參數進行傳遞。安全
• 委託可用於定義回調方法。ide
• 委託能夠連接在一塊兒;例如,能夠對一個事件調用多個方法。函數
•方法沒必要與委託簽名徹底匹配。 有關更多信息,請參見 在委託中使用變體(C# 和 Visual Basic)。ui
• C# 2.0 版引入了匿名方法的 概念,此類方法容許將代碼塊做爲參數傳遞,以代替單獨定義的方法。 C# 3.0 引入了 Lambda 表達式,利用它們能夠更簡練地編寫內聯代碼塊。 匿名方法和 Lambda 表達式(在某些上下文中)均可編譯爲委託類型。 這些功能統稱爲匿名函數。 有關 lambda 表達式的更多信息,請參見 匿名函數(C# 編程指南)。this
委託是一種定義方法簽名的類型。 當實例化委託時,您能夠將其實例與任何具備兼容簽名的方法相關聯。 您能夠經過委託實例調用方法。spa
委託用於將方法做爲參數傳遞給其餘方法。 事件處理程序就是經過委託調用的方法。 您能夠建立一個自定義方法,當發生特定事件時某個類(例如 Windows 控件)就能夠調用您的方法。 .net
例子1:指針
class Program { static void Main(string[] args) { Hello(); } static void Hello() { System.Console.WriteLine("Hello, Delegate!"); } }
這是一個常見的方法, 輸出一段字符串Hello, Delegate!
下面咱們來把他寫成委託,
class Program { delegate void PrintHello(); static void Main(string[] args) { PrintHello ph = new PrintHello(Hello); ph.Invoke(); } static void Hello() { System.Console.WriteLine("Hello, Delegate!"); } }
這裏的PrintHello的方法類型須要和Hello保持一直,另外參數也須要保持一致,如今是無參數的.講Hello做爲參數傳到委託中,而後用Invoke調用.
以上代碼也會輸出,Hello, Delegate!由於invoke了這個方法.
從.net 2.0開始就使用匿名委託, 能夠這樣申明
delegate { };
或者帶參數的
delegate (string i){ };
{}括號中能夠寫須要執行的邏輯代碼.
有了匿名委託咱們就能夠偷一下懶了,能夠把上面的例子改爲以下:
class Program { delegate void PrintHello(); static void Main(string[] args) { PrintHello ph = delegate { System.Console.WriteLine("Hello, Delegate!"); }; ph.Invoke(); } //static void Hello() //{ // System.Console.WriteLine("Hello, Delegate!"); //} }
在.net 3.0中新加了Action<T> 無返回的委託, Predicate<T>有返回值,且返回true或false的委託.
咱們能夠將上面的例子改爲有參數的,
class Program { static Action<string> print = delegate(string i) { System.Console.WriteLine("Hello, {0}!",i); }; static void Main(string[] args) { print.Invoke("Delegate"); } }
或者用lambda表達式替代匿名委託,進一步偷懶..
class Program { static Action<string> print = (i)=>{ System.Console.WriteLine("Hello, {0}!",i); }; static void Main(string[] args) { print.Invoke("Delegate"); } }
以上會輸出Hello,Delegate!由於將Delegate傳入到最後輸出.
再來說解一下Predicate這個只返回true or false的委託,以下:
class Program { static Predicate<string> print = (i) => { return string.IsNullOrEmpty(i); }; static void Main(string[] args) { System.Console.WriteLine(print.Invoke("Hello, Delegate!")); } }
以上代碼會輸入true由於i不是爲null or empty.
在.net 3.5中又新加了Action(無返回值的委託,相似於delegate void)和Func<T,T> 帶返回參數的,參數類型是T,返回類型也能夠是int,string等..
因此剛纔的無參數的例子又能夠寫成這樣:
class Program { static Action print = () => { System.Console.WriteLine("Hello, Delegate!"); }; static void Main(string[] args) { print.Invoke(); } }
再來看看Func<T,TReslut> 第一個T表明參數的類型,第一個TReslut表明返回結果的類型。
以下,參數的類型是int,返回的類型是string.
class Program { static Func<int,string> print = (i) => { return "Hello, Delegate!"+i.ToString(); }; static void Main(string[] args) { System.Console.WriteLine(print.Invoke(0)); } }
輸出的結果是:Hello, Delegate!0
再來看看委託的回調函數,以下:
class Program { delegate string callback(string firstName, string lastName); static void Main(string[] argss) { DoCallback("Charlie", "Wang", en_US); DoCallback("Tom", "Chen", ch_ZN); } static void DoCallback(string firstName, string lastName, callback call) { string result=call(firstName, lastName); Console.WriteLine(result); } static string en_US(string firstName, string lastName) { return firstName + " ," + lastName; } static string ch_ZN(string firstName, string lastName) { return lastName+", "+firstName; } }
輸出的結果爲:
Charlie ,Wang
Chen, Tom
咱們還能夠將以上代碼進一步精簡,用Func代替.
class Program { static void Main(string[] argss) { DoCallback("Charlie", "Wang", en_US); DoCallback("Tom", "Chen", ch_ZN); } static void DoCallback(string firstName, string lastName, Func<string,string,string> callback) { string result = callback(firstName, lastName); Console.WriteLine(result); } static string en_US(string firstName, string lastName) { return firstName + " ," + lastName; } static string ch_ZN(string firstName, string lastName) { return lastName+", "+firstName; } }
咱們還能夠這樣寫.
class Program { static void Main(string[] argss) { DoCallback("Charlie", "Wang", en_US); DoCallback("Tom", "Chen", ch_ZN); DoCallback("Kevin", "Liu", (lastName, firstName) => { return string.Format("This is {0} {1}", lastName, firstName);}); } static void DoCallback(string firstName, string lastName, Func<string,string,string> callback) { string result = callback(firstName, lastName); Console.WriteLine(result); } static string en_US(string firstName, string lastName) { return firstName + " ," + lastName; } static string ch_ZN(string firstName, string lastName) { return lastName+", "+firstName; } }
輸出結果爲:
Charlie ,Wang
Chen, Tom
This is Kevin Liu
委託在不少時候使用能夠精簡咱們的代碼,看起來比較直觀,下面是個很經典的案例:
class Program { static void Main(string[] args) { B b = new B(); } } class A { public A() { Print(); } public virtual void Print() { } } class B : A { int x = 1; int y; public B() { y = -1; } public override void Print() { System.Console.WriteLine("x={0},y={1}", x, y); } }
各位讀者看看以上代碼輸出什麼?
class Program { static void Main(string[] args) { B b = new B(); b.print(); } } class A { public A() { Print(); } public virtual void Print() { } } class B : A { int x = 1; int y; public Action print = delegate { }; public B() { y = -1; this.print = Print; } public override void Print() { System.Console.WriteLine("x={0},y={1}", x, y); } }
而後再看看以上代碼又輸出什麼?