學習委託筆記

2021-06-13 02:40:38 字數 3539 閱讀 7520

最近一直在想如何解釋委託,比如乙個婚姻律師事務所,他處理婚姻相關的案子,這些案子的共同點都屬於婚姻調解類別,不同點就是各個案子的當事人不一樣,案子處理的方式不一樣.這和委託有什麼關係呢,這個例子裡面,我們可以把婚姻律師事務所當作乙個委託,而針對每個不同當事人處理方式不一樣,我們可以理解為具體實現的不同函式.簡單來說,事務所為委託,只要與其簽名(返回值和引數)相同的函式都可以掛在這個委託下來呼叫,上面的婚姻自然可以理解為事務所的標籤.

為什麼要引入委託?

首先我們來看看乙個小場景.

經理有四個秘書,分管不同業務,經理辦公室有一**,設定按鍵1接通秘書1,按鍵2接通秘書2........

我們有以下**:

void 接秘書1()

void 接秘書2()

void 經理**()

if(按鍵==2)

}

從上面簡易**中,我們看到接秘書1()和接秘書2()**中的注釋"其他**"應該是相同的**,獲取她們可以提取到經理**()方法的最上端以精簡**.但如果碰到foreach一類的**,這種遷移自然是不明智的.現在要把//其他**部分抽離出來,讓其和具體業務形式分離開來,即抽象出來.

void 接秘書1()

void 接秘書2()

void dosomething(接秘書 jms)

如上,dosomething()方法中有可以抽離的**,但需要乙個接秘書()的方法,這個方法可以代表接秘書1(),接秘書2()等多個方法.那現在就涉及到委託,委託為引用型別,是乙個類,她定義了方法型別,如同string定義乙個字串a,而a可以被當作函式引數來傳遞,而委託delegate也可以定義乙個型別b,而b同樣也可以作為函式引數來傳遞.說到這裡,上面**中,我們只需要宣告乙個接秘書()方法的委託即可代表一系列此類方法.

public delegate void 接秘書();
而我們只需要指定進入dosomething(接秘書 jms)方法時,該委託使用哪個接秘書方法即可,如下.

void 經理**()

if(按鍵==2)

接**(jdh);//呼叫委託

}

以上我們關心的重點是接通**,而並不關心接通**到誰,接通到誰是業務具體,在物件導向設計中,應該盡量從具體業務中抽離出一些與業務無關的通用模型,增加**重用性,同時也使得這個**精簡.

我們再看一下在開發中,應該很少這麼用.實際的開發中對委託用的做多的是事件,事件是以委託為基礎衍生出來的,在.net中,介面上控制項的事件都是通過委託來實現的,可以說委託無處不在,這也是我們為什麼引入委託的原因,.net有自己系統自帶的事件,而我們也可以自定義事件來為我們的業務服務,比如訂閱模式中對委託事件的應用.

首先,是.net在委託上的一些應用,這些可以讓我們表層上寫出更好看的**,從2.0的匿名委託到3.0的lambda表示式,讓我們的**看起來更加直觀,行雲流水般漂亮.下面通過幾個例子來看看同樣功能函式的版本公升級.

public delegate int getmul(int x,int y);

int vismul(int a,int b)

void main()

上面的**實現輸出兩個整數的乘積.先宣告乙個getmul委託;之後寫乙個函式,返回兩個整數的乘積;主函式初始化委託,然後傳遞給委託兩個整數5,3,輸出為15.

這種是最直接對委託進行實用的方式,在2.0版本中,引入了匿名函式,我們可以看看如下**,看看哪些地方得到了簡化.

public delegate int getmul(int x,int y);

void main()

; console.writeline(gm(5,3).tostring());

}

如上即為匿名方式的實現,看看**比之前的精簡了什麼,精簡的主要是具體函式定義部分,自然這種方式並不適用於那些經常被其他方法呼叫的函式.在使用過程中,對於那些有可能不怎麼使用,或者只是在此方法中使用一次的函式,我們可以直接通過匿名函式來實現,至少能簡化**,下面我們再看看3.0中的lambda表示式,如下**.

void main()

以上的寫法表層**更為簡潔,甚至不用定義委託了.func是3.5版中的一種委託簡寫方式,可以理解為微軟對委託的一種封裝,和action類似,action指定那些只有輸入引數,沒有返回值的委託;func相反是有返回值,所以我們在寫**中,碰到委託可以想象是否可以用到這兩種委託的簡寫方式.下面給乙個action的使用方法簡例.

void main()

; stringbuilder resultmsg = new stringbuilder();

ids.foreach(new action((int id) =>

));console.writeline(resultmsg.tostring());

}
action表示乙個輸入為int的委託,而上面的例子用到了lambda表示式,(int id)=>{}實際上與 delegate(int id){}等價,這個熟練了自然會信手拈來.

就開發中那些地方用到委託這個命題,以上的這段內容只是在**技巧上對委託進行了封裝或者說表層上的簡化,讓編碼者更加自然的編碼,實際上我覺得微軟總體上來說想把**也變得如同漢字般象形,寫起來更加合乎自然法則,面向自然.呵呵!

除了這些應用以外,自然在實際的運用中,我們通過委託帶來方便,比如類間傳遞複雜的引數,list集合等,我們可以通過委託來實現,實際上這個類之間傳遞引數和觀察者模式有些關係(observer),這裡不詳細介紹了.

最後來說說事件,如同屬性對字段的封裝一樣,事件就是對委託的封裝,他讓委託更加安全,我們只通過+=和-=對事件進行註冊和登出,而無法對事件進行直接=.我們來看看微軟在.net中自帶的委託事件.

public delegate void eventhandler(object sender, eventargs e);
當我們生成乙個按鈕事件時,系統自動會生成下面**:

this.button1.click += new system.eventhandler(this.button1_click);
意思就是,button1按鈕的click事件觸發時,執行button1_click這個函式方法,在eventhandler(object sender, eventargs e)這個委託中,object代表觸發主體,eventargs**其主體相關引數資訊,咋們再看看其click事件定義.

public event eventhandler click;
即是對eventhandler委託的乙個封裝,整個事件過程既是click觸發繫結在其上的委託方法button1_click.其實可以想一樣,微軟這個事件機制本身就實現了一種設計模式,至於.net內部是如何知曉這個事件,並為其生成事件**,太深奧.實際上用**來實現的一些設計模式,在微軟設計自己的vs時,已經用過了.

暫時了解的就這麼多,就到這了,第一次寫技術部落格,望大家指教!

委託學習筆記

1 申明委託 delegate void mydel int x 2 建立委託物件 1 使用new運算子的物件建立表示式 mydel delvar delvar new mydel myinstobject.mym1 使用例項方法 dvar new mydel sclass.mym1 使用靜太方法 ...

C 「委託」學習筆記

using system using system.collections.generic using system.linq using system.text namespace delegatetest console.writeline sh3 jiang 組合委託,此時委託就能夠依次執行多...

C 學習筆記 委託

什麼是委託?委託 delegate 是一種可以把引用儲存為函式的型別。委託的宣告非常類似於函式,但不帶函式體 且要使用 delegate關鍵字。委託的宣告指定了乙個型別和引數列表。在定義了乙個委託後就可以宣告該委託型別的變數。接著把這個變數初始化為與委託有相同返回型別和引數列表的函式引用。之後,就可...