C#2.0 委托

委托

委托是一個非常不錯的設計,允許我們把方法做為參數傳遞,實現了開放閉放原則。在方法中我們只要有一個委托占位,調用者就可以傳入符合簽名的方法來做不同的操作,這也面向對象開發中多態的魅力。

但是在C#1.0的時候,委托寫起來實際上是非常復雜的,首先我們要聲明一個委托,然后再寫一個符合委托簽名的方法。再創建委托實例。然后才是調用,比如下面一個簡單的例子,我要在winform程序中用戶按了按鍵后我需要彈出一個消息

因為委托的聲明已經內置了,也就是KeyPressEventHandler所以我不用去寫。簡單一看似乎挺簡潔,但是在winForm程序中會有著大量的事件,有些事件可能處理的方式非常簡單,但是我們需要去相應的寫一個方法。這也是比較頭疼的問題。下面我們來看如何優化這個代碼

? ?

方法組

在這面我們創建了一個委托實例,在C#1.0中,要同時指定委托類型和方法(操作)也就是如下圖

而在C#2.0中支持從方法組到一個兼容委托的隱式轉換,也就是如果方法簽名和委托聲明完全相同,那么就不必再去new一個委托。這時代碼就變成了

? ?

但是有些方法并不是可以進行隱式轉換的,如果方法需要一個Delegate類型的參數,那么我們的方法就不適用了,比如Invoke方法。這些我們就要顯示轉換

? ?

? ?

協變與逆變

很多人都以為這是在4.0中才支持的,因為那時有了泛型的可變性。不過這個委托的可變性完全不同。

winform中給我們內置很多的委托類型,比如上面用到的KeyPressEventHandler,還有MouseEventHandler,他們實際上區別不大,只是參數類型不同。第一個參數類型是KeyPressEventArgs,第二個是MouseEventArgs

不同的事件對應不同的處理,這是沒有問題的。但是我們可能會有不同的事件同樣的處理這種需求。在C#1.0中很遺憾是沒有辦法的。而在C#2.0中我們可以使用逆變來解決這個問題

KeyPressEventArgsMouseEventArgs都派生與EventArgs類型。實際上EventArgs的派生類有多達數百個。

我們只需要有一個具有EventAgrs類型的方法,就可以這么去做

? ?

一個返回類型為基類的委托,我們想要用子類去實例化這個委托,這在之前是不可能的。而在C#2.0中,這已經沒有任何問題

? ?

? ?

? ?

匿名方法

C#2.0中設計者也意識到了創建一個委托的步驟過于繁瑣,我們要有一個完整的方法,然后再創建委托實例進行調用,在C#2.0中則出現了匿名方法來幫助我們簡化這一流程(3.0中的拉姆達則更加的方便)

下面就是一個簡單的匿名方法創建委托實例的例子,拿到一個字符串然后去除兩邊空格打印出來

? ?

雖然我們創建的是一個委托方法,但是編譯成IL后每個匿名方法都會創建一個方法,會在匿名方法所在的類生成一個方法不過方法名則是亂七八糟的,不過也不是給程序員去看的。

? ?

閉包

使用方法就會使用到變量,對于匿名方法來說,分為外部變量與局部變量。很容易理解,外部變量就是匿名方法外聲明的變量,而局部變量就是匿名方法內聲明的變量。

如果匿名方法沒有使用任何外部變量,那么則相安無事。如果使用了外部變量,那么它就是被捕獲的外部變量。在匿名方法內對該變量的操作是有效的!

為什么要說閉包,是因為匿名方法會在特成的情況下延長變量的生命周期,為什么這么說呢,大家都知道委托是方法的類型,可以把方法作為委托進行返回,如果一個方法里有一個委托實例,使用的是匿名方法并且捕獲了外部變量,然后把這個委托實例進行返回。這時就形成了一個閉包

? ?

這時如果去看IL會發現創建了一個新的類去容納i變量,這也是為什么方法結束后i變量仍然存在的原因,還有一點需要注意的,外部變量只有一個,如果多個匿名方法捕獲了它,那么這些匿名方法使用的都是一個變量,局部變量則沒有這個問題

循環中創建的變量,每個委托捕獲到的都是不同的變量

? ?

我們需要牢記的是

  • 補獲的是變量,百不是創建委托初值時它的值
  • 捕獲的變量生命周期被延長,至少和捕捉它的委托一樣長
  • 多個委托可以捕獲同一個變量
  • 必要時創建額外的類型來保存捕獲變量

轉載于:https://www.cnblogs.com/LiangSW/p/7203843.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/253989.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/253989.shtml
英文地址,請注明出處:http://en.pswp.cn/news/253989.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

qt亂碼Could not decode“xxx.cpp“ with “UTF-8“-encoding.Editing not possible問題處理

問題描述:如題: 解決方法: 1、點擊Select Encoding按鈕 2、選擇按照系統編碼 3、選中System后點擊按編碼重新載入 4、問題解決

bootargs中的環境變量說明和一些常用的uboot命令

bootargs中的環境變量說明和一些常用的uboot命令 一些常見的uboot命令: Help [command]在屏幕上打印命令的說明 Boom [addr]啟動在內存儲器的內核 Tftpboot通過tftp啟動內核 Saveenv保存環境變量 setenv name [value] 設置環境變量 bootargs中的環境變量 co…

特斯拉自動駕駛系統秘密,來自特斯拉AI總監爆料

據外媒報道,特斯拉汽車公司人工智能(AI)總監安德烈卡帕西(Andrej Karpathy)日前參加2018年TRAIN AI大會時,剖析了該公司構建自動駕駛儀(Autopilot)計算機視覺解決方案的方法。據介紹,Autopilot編…

快捷鍵匯總

navicat 運行選中代碼 ctrshiftr navicat 運行所有代碼 ctrr 快速顯示桌面 wind 轉載于:https://www.cnblogs.com/caer/p/6064571.html

js做倒計時

var dinshiqi setInterval(timerun,1000) function timerun(){ //timegundong var now_time new Date(); var hours now_time.getHours(); //時 var minutes now_time.getMinutes(); //分 var seconds now_time.getSeconds(); //秒 //秒鐘 show_seconds 59 - parseInt(s…

QT右鍵點擊添加庫不響應的解決辦法

問題描述 QT在pro右鍵點擊添加庫不響應 解決方案 雙擊打開pro文件 在pro文件界面里單擊鼠標右鍵,并選擇添加庫。 解決問題

爬取前塵無憂python職位信息并保存到mongo數據庫

1.re實現 1 import re,os2 import requests3 from requests.exceptions import RequestException4 5 MAX_PAGE 10 #最大頁數6 KEYWORD python7 headers {8 User-Agent:9 Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, lik…

實驗八——函數定義及調用總結

1.本次課學習到的知識點: (1)學習了數字金字塔。pyramid ()函數功能,函數定義時,形參n決定數字金字塔的層數; (2)不返回結果的函數定義: (3)復數運算: c1x1(y1) i,c2x2(y…

Apache JMeter 記一次使用HTTP工具POST提交JSON數據進行送積分高并發壓測(二)

一、前言 前面文章已經介紹Apache JMeter的基本概率和如果使用,但作為一個開發人員,自己寫的代碼都應該要好好的COD EREVIEW,好好的自測吧。但是有些場景比如高并發、負載和性能測試的時候,不借助工具是不好進行測試的。Jmter工具設計之初是用…

QT pro文件詳解

1.QT pro文件配置項說明 注釋:注釋是從一行的#開始,到這一行的結束。QT :這個是添加QT項目需要的模塊的,若項目中要排除某個模塊,也可用QT -配置項。TEMPLATE : 這個配置項確定qmake為這個應用程序生成哪種makefile …

可伸縮視頻編碼svc

可伸縮視頻編碼(Scalable Video Coding, SVC)技術把視頻信號編碼成分層的形式,當帶寬不足時只對基本層的碼流進行傳輸和解碼,但這時解碼的視頻質量不高。當帶寬慢慢變大時,可以傳輸和解碼增強層的碼流來提高視頻的解碼…

【vim】幾種模式的切換

很多初學者啟動vim后,不知道怎么輸入字符:按了半天字母,結果屏幕還是空的。 vim和記事本或WORD不一樣,不是一打開后就可以輸入文字,此時它處于正常模式。 vim一共有4個模式: 正常模式 (Normal-mode) 插入模…

數據結構----順序表與單鏈表(JAVA)

下面為學習順序表和單鏈表的一些基本操作函數&#xff1a; 1 public class SeqList<T> extends Object {2 protected int n;3 protected Object[] element;4 5 public SeqList(int length) {6 this.element new Object[length];7 this.n 0…

SSH初體驗系列--Hibernate--1--環境配置及demo

最近在學hibernate,常見的教程都是搭配mysql,因為公司本地電腦用的是pg,所以就嘗試著做個pg的小demo. 自己也是邊學邊寫&#xff0c;只當是加深印象.話不多說&#xff0c;直接開始; 一) 準備工作; 1) 本地安裝postgresql ,這個不多說&#xff0c;自己去網上下載; 注: 本次使用的…

Qt學習:QAction系列詳解

一、QAction類詳解 【詳細描述】 QAction類提供了抽象的用戶界面action&#xff0c;這些action可以被放置在窗口部件中。 應用程序可以通過菜單&#xff0c;工具欄按鈕以及鍵盤快捷鍵來調用通用的命令。由于用戶期望每個命令都能以相同的方式執行&#xff0c;而不管命令所使用的…

H.264優秀特征

一、主要特性 1、H.264/AVC相對以前的編碼方法&#xff0c;以MPEG-2為例&#xff0c;在圖像內容預測方面提高編碼效率&#xff0c;改善圖像質量的主要特點如下&#xff1a; ● 可變塊大小運動補償&#xff1a; 選擇運動補償大小和形狀比以前的標準更靈活&#xff0c;最小的…

Linux 文件系統 EXT4 的前世今生

在先前關于Linux文件系統的文章中&#xff0c;我寫了一份說明書去介紹Linux文件系統&#xff0c;里面有一些高級的概念&#xff0c;比如說&#xff0c;一切都是文件。我很想去深入地討論更多EXT文件系統的特性的信息。所以&#xff0c;首先讓我們來回答這個問題&#xff1a;什么…

windows 添加開始菜單

C:\Users\用戶名&#xff08;為你設置的電腦名稱&#xff09;\AppData\Roaming\Microsoft\Windows\Start Menu C:\ProgramData\Microsoft\Windows\Start Menu 注&#xff1a;默認狀態下AppData和ProgramData文件夾為隱藏狀態&#xff0c;所以要查看需要先顯示隱藏的文件。 具體…

awesome-go:很全的go語言資源合集

awesome-go:一個很全的go語言框架&#xff0c;庫&#xff0c;軟件合集 前面發過關于awsone-python, awsone django&#xff0c; flask。最近在學習golang&#xff0c;所以找到awsone-go 非常贊的go語言 Audio & 音樂類安全認證 & OAuthCUI數據庫數據庫驅動日期時間Emai…