自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

各版本.NET委托的寫法回顧

開發(fā) 后端
本文講述了各版本.NET委托寫法的變化。當(dāng)然,委托本身其實(shí)從來沒有改變過,改變的一直都是委托的“寫法”。

在《關(guān)于最近面試的一點(diǎn)感想》一文中,Michael同學(xué)談到他在面試時詢問對方“delegate在.net framework1.1,2.0,3.5各可以怎么寫”這個問題。于是乎,有朋友回復(fù)道“請問樓主,茴香豆的茴有幾種寫法”,“當(dāng)代孔乙己”,獨(dú)樂,眾樂??戳怂械脑u論,除了某些朋友認(rèn)為“的確不該不知道這個問題”之外,似乎沒有什么人在明確支持樓主。

不過我支持,為什么?因?yàn)槲乙蔡徇^出這樣的問題:各版本.NET委托的寫法有何不同?

這樣,我們暫且不提應(yīng)聘“高級開發(fā)人員”的人,在“自稱熟悉各版本.NET框架”的前提下,是否應(yīng)該知道這個答案。我們也暫且不提Michael同學(xué)提問的“目的”是什么。老趙就先單獨(dú)針對這個問題進(jìn)行解釋,然后談?wù)勛约簽槭裁磿岢鲞@個問題吧。

可能有一件事情需要說在前面,那就是:委托本身其實(shí)從來沒有改變過,改變的一直都是委托的“寫法”。因此更確切地說,改變的只是“編譯器”。而本文所有內(nèi)容都用C#來實(shí)現(xiàn),其實(shí)談得也都是C#編譯器本身——但是其實(shí)VB.NET也有變化埃再由于.NET版本和C#版本的關(guān)系也是非常密切的,因此全文就使用.NET版本進(jìn)行指代了。

.NET 1.x中委托的寫法

委托,如果不追究細(xì)節(jié),從表面上來看我們可以將其通俗地理解為一個安全的“函數(shù)指針”。當(dāng)然,這個函數(shù)指針其實(shí)也是一個對象,有自己的成員,也會封裝了被調(diào)用方的上下文等等。至于委托的定義和使用方式,則是這樣的:

  1. public delegate int SomeDelegate(string arg1, bool arg2);  
  2.  
  3. public static int SomeMethod(string arg1, bool arg2) { return 0; }  
  4.  
  5. public class SomeClass  
  6. {  
  7.     public int SomeMethod(string a1, bool a2) { return 0; }  
  8.  
  9.     public event SomeDelegate SomeEvent;  
  10. }  
  11.  
  12. static void Main(string[] args)  
  13. {  
  14.     SomeClass someClass = new SomeClass();  
  15.     SomeDelegate someDelegate = new SomeDelegate(someClass.SomeMethod);  
  16.  
  17.     someClass.SomeEvent += new SomeDelegate(SomeMethod);  
  18. }  
  19.  

可見,在.NET 1.x中需要使用new DelegateType(...)的方式來創(chuàng)建一個委托對象。不過,作為委托對象內(nèi)部的方法它既可以是實(shí)例方法,也可以是靜態(tài)方法。此外,方法只需要匹配委托類型的簽名和返回值即可,方法參數(shù)的名稱不會成為約束。

嗯,就是這么簡單。

.NET 2.0中委托的寫法

.NET委托引入了范型,且寫法略有簡化:

  1. public delegate TResult MyFunc(T1 a1, T2 a2);  
  2.  
  3. public static int SomeMethod(string a1, bool a2) { return 0; }  
  4.  
  5. static void Main(string[] args)  
  6. {  
  7.     MyFunc<stringboolint> myFunc = SomeMethod;  
  8. }  
  9.  

在.NET 2.0中,new DelegateType已經(jīng)可以省略,開發(fā)人員可以直接將方法賦值給一個委托對象的引用。當(dāng)然,這個改進(jìn)不值一提,.NET 2.0中委托寫法的關(guān)鍵在于引入了“匿名方法”:

  1. public static void TestRequest(string url)  
  2. {  
  3.     WebRequest request = HttpWebRequest.Create(url);  
  4.     request.BeginGetResponse(delegate(IAsyncResult ar)  
  5.     {  
  6.         using (WebResponse response = request.EndGetResponse(ar))  
  7.         {  
  8.             Console.WriteLine("{0}: {1}", url, response.ContentLength);  
  9.         }  
  10.     },  
  11.     null);  
  12. }  

匿名方法,簡單地說就是內(nèi)聯(lián)在方法內(nèi)部的委托對象,它的關(guān)鍵便在于形成了一個閉包(委托執(zhí)行時所需的上下文)。如上面的代碼中,BeginGetResponse的***個參數(shù)(委托)可以直接使用TestRequest方法的參數(shù)url,以及方法內(nèi)的“局部”變量request。如果沒有匿名函數(shù)這個特性的話,代碼寫起來就麻煩了,例如在.NET 1.x中您可能就必須這么寫:

  1. public static void TestRequest(string url)  
  2. {  
  3.     WebRequest request = HttpWebRequest.Create(url);  
  4.     object[] context = new object[] { url, request };  
  5.     request.BeginGetResponse(TestAsyncCallback, context);  
  6. }  
  7.  
  8. public static void TestAsyncCallback(IAsyncResult ar)  
  9. {   
  10.     object[] context = (object[])ar.AsyncState;  
  11.     string url = (string)context[0];  
  12.     WebRequest request = (WebRequest)context[1];  
  13.  
  14.     using (WebResponse response = request.EndGetResponse(ar))  
  15.     {  
  16.         Console.WriteLine("{0}: {1}", url, response.ContentLength);  
  17.     }  
  18. }  
  19.  

此時,我們往往會發(fā)現(xiàn),開發(fā)人員需要花費(fèi)大量的精力,為一小部分代碼維護(hù)一大段上下文。例如在這段代碼中,我們會將url和request對象塞入一個object數(shù)組中,在回調(diào)函數(shù)中再通過危險(xiǎn)的Cast操作恢復(fù)數(shù)據(jù)。如果您希望“強(qiáng)類型”,那么只能為每個回調(diào)創(chuàng)建一個新的上下文對象,維護(hù)起來可能更加麻煩——要知道,在并行編程,異步調(diào)用越來越重要的今天,如果沒有匿名方法自動保留上下文的特性,開發(fā)人員會為這些“額外工作”疲于奔命的。

可能您會說,匿名方法的可讀性不佳,因?yàn)樾枰皟?nèi)聯(lián)”。一個方法中內(nèi)聯(lián)太多,維護(hù)成本就上去了,所以匿名方法并不推薦使用。我想說的是,您錯了。如果為了可維護(hù)性,要將方法獨(dú)立拆開,也可以利用匿名方法的優(yōu)勢:

  1. public static void TestRequest(string url)  
  2. {  
  3.     WebRequest request = HttpWebRequest.Create(url);  
  4.     request.BeginGetResponse(delegate(IAsyncResult ar)  
  5.     {  
  6.         TestAsyncCallback(ar, request, url);  
  7.     }, null);  
  8. }  
  9.  
  10. public static void TestAsyncCallback(IAsyncResult ar, WebRequest request, string url)  
  11. {  
  12.     using (WebResponse response = request.EndGetResponse(ar))  
  13.     {  
  14.         Console.WriteLine("{0}: {1}", url, response.ContentLength);  
  15.     }  
  16. }  
  17.  

如果借助.NET 3.5中的Lambda表達(dá)式,代碼可以寫的更簡單易讀:

  1. public static void TestRequest(string url)  
  2. {  
  3.     WebRequest request = HttpWebRequest.Create(url);  
  4.     request.BeginGetResponse(ar => TestAsyncCallback(ar, request, url), null);  
  5. }  
  6.  

以上就總結(jié)了各版本.NET委托的寫法。

【編輯推薦】

  1. C# Actor模型開發(fā)實(shí)例:網(wǎng)絡(luò)爬蟲
  2. 強(qiáng)類型和Actor:ActorLite的演示
  3. C#的Tag Message回顧:繁瑣而危險(xiǎn)
  4. Erlang的Actor回顧:將消息轉(zhuǎn)化為邏輯執(zhí)行
  5. Actor模型的本質(zhì):究竟是要解決什么問題
責(zé)任編輯:yangsai 來源: 老趙點(diǎn)滴
相關(guān)推薦

2009-04-01 12:00:43

ASP.NETMVC

2009-08-11 08:15:12

Silverlight

2009-08-18 11:08:24

.Net Framew

2009-09-02 17:51:36

.NET委托

2009-10-15 09:12:29

.NET委托

2024-01-15 00:30:04

Python 3語言版本

2011-05-25 09:52:40

Fedora 15

2010-01-05 18:21:33

.NET Framew

2011-06-16 15:14:17

VB.NET事件委托

2011-06-21 13:23:20

Qt 版本

2010-08-03 08:52:23

委托接口

2011-05-20 16:33:47

委托接口

2017-11-07 12:53:28

Android支持庫

2012-04-13 09:13:47

Java

2015-09-28 10:12:53

Windows 10版本激活

2021-08-29 18:01:57

HTTP協(xié)議版本

2009-06-30 08:35:51

微軟Windows 7操作系統(tǒng)

2017-01-05 18:47:26

Windows 10操作系統(tǒng)微軟

2019-07-05 08:47:26

Windows 10專業(yè)版企業(yè)版

2012-04-27 09:21:36

Ubuntu 12.0
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號