成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

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

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

在《關于最近面試的一點感想》一文中,Michael同學談到他在面試時詢問對方“delegate在.net framework1.1,2.0,3.5各可以怎么寫”這個問題。于是乎,有朋友回復道“請問樓主,茴香豆的茴有幾種寫法”,“當代孔乙己”,獨樂,眾樂。看了所有的評論,除了某些朋友認為“的確不該不知道這個問題”之外,似乎沒有什么人在明確支持樓主。

不過我支持,為什么?因為我也提過出這樣的問題:各版本.NET委托的寫法有何不同?

這樣,我們暫且不提應聘“高級開發人員”的人,在“自稱熟悉各版本.NET框架”的前提下,是否應該知道這個答案。我們也暫且不提Michael同學提問的“目的”是什么。老趙就先單獨針對這個問題進行解釋,然后談談自己為什么會提出這個問題吧。

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

.NET 1.x中委托的寫法

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

  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(...)的方式來創建一個委托對象。不過,作為委托對象內部的方法它既可以是實例方法,也可以是靜態方法。此外,方法只需要匹配委托類型的簽名和返回值即可,方法參數的名稱不會成為約束。

嗯,就是這么簡單。

.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已經可以省略,開發人員可以直接將方法賦值給一個委托對象的引用。當然,這個改進不值一提,.NET 2.0中委托寫法的關鍵在于引入了“匿名方法”:

  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. }  

匿名方法,簡單地說就是內聯在方法內部的委托對象,它的關鍵便在于形成了一個閉包(委托執行時所需的上下文)。如上面的代碼中,BeginGetResponse的***個參數(委托)可以直接使用TestRequest方法的參數url,以及方法內的“局部”變量request。如果沒有匿名函數這個特性的話,代碼寫起來就麻煩了,例如在.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.  

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

可能您會說,匿名方法的可讀性不佳,因為需要“內聯”。一個方法中內聯太多,維護成本就上去了,所以匿名方法并不推薦使用。我想說的是,您錯了。如果為了可維護性,要將方法獨立拆開,也可以利用匿名方法的優勢:

  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表達式,代碼可以寫的更簡單易讀:

  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.  

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

【編輯推薦】

  1. C# Actor模型開發實例:網絡爬蟲
  2. 強類型和Actor:ActorLite的演示
  3. C#的Tag Message回顧:繁瑣而危險
  4. Erlang的Actor回顧:將消息轉化為邏輯執行
  5. Actor模型的本質:究竟是要解決什么問題
責任編輯:yangsai 來源: 老趙點滴
相關推薦

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委托

2010-01-05 18:21:33

.NET Framew

2011-06-16 15:14:17

VB.NET事件委托

2024-01-15 00:30:04

Python 3語言版本

2011-05-25 09:52:40

Fedora 15

2010-08-03 08:52:23

委托接口

2011-05-20 16:33:47

委托接口

2011-06-21 13:23:20

Qt 版本

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協議版本

2009-08-10 09:41:07

.NET Lambda

2009-06-30 08:35:51

微軟Windows 7操作系統

2017-01-05 18:47:26

Windows 10操作系統微軟

2023-04-10 07:47:01

流程引擎Flowable
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 99精品久久 | 国产91视频免费 | 欧美二区在线 | 亚洲精品v日韩精品 | 中文字幕在线观看第一页 | 中文字幕精品一区 | 欧美综合国产精品久久丁香 | 久久69精品久久久久久久电影好 | 国内自拍偷拍一区 | 国产精品亚洲一区 | 粉色午夜视频 | 日韩成人精品在线 | av大全在线观看 | 日韩成人精品 | 99热在线免费 | 999免费网站 | 天天色天天射天天干 | 999久久久 | 久久国产视频一区 | 国产免费一区二区三区网站免费 | 久久福利电影 | 亚洲一区二区三区在线视频 | 超碰免费在线 | 欧美日韩三级视频 | 亚洲综合成人网 | 欧美三级电影在线播放 | 欧美电影免费网站 | 国产精品美女一区二区三区 | 天天看天天爽 | 中文字幕在线观看一区 | 一区二区三区在线 | 国产视频久久 | 国产一区二区三区www | 97国产精品视频人人做人人爱 | 精品国产欧美一区二区 | 一区二区三区四区在线 | 色综合美女 | 日韩最新网址 | 青青久草 | 欧美中文一区 | 日韩一级黄色片 |