據說c#的委託跟c++的函式指標很相似,c中的函式指標是n年前學習的,基本上對他不了解,這也是半路出家者在學習中所不得不承擔的困難。關於委託,看過很多書和很多文章,反覆下來,研讀的次數大概不會少於15遍,但每次都似懂非懂。並不是像我這樣的菜鳥不懂,就連高手往往也介於懂與不懂之間,彷彿如果昨天高手還理解委託的意義,經過一夜長眠,今天就不懂了。高手給菜鳥講解的過程中,很容易就中了菜鳥的「圈套」,跌落到跟菜鳥一樣的境界(我就這樣對付過乙個高手)。
如果說我現在已經理解了委託的意義,我想那基本上是不可能的,這可能需要長期的琢磨,好像是練習的是一種精神境界,而不是一種技術。但這幾天做的乙個事情,卻使我對委託的好處有了進一步的了解。事情這這樣的,假設有兩個窗體form1和form2,form1裡面有乙個datagrid控制項,form2裡有乙個mapcontrol控制項(arcengine),datagird和mapcontrol分別用於盛放feature的屬性資訊和圖形,要求當選中datagrid中一行的時候,mapcontrol中相應feature高亮顯示,當選中mapcontrol中的乙個feature時,datagrid選中的行也要隨之移動到相通的紀錄上,就類似於arcmap中,屬性表的一行和地圖視窗的feature要一一對應的、互動的進行選擇一樣。
我們可以把form2的乙個物件作為form1的乙個成員變數,這樣就可以通過form1窗體來控制作為其成員的form2例項,但是如果同樣要求form2控制form1窗體中的datagrid的話,就要把datagrid作為引數傳遞給form2窗體(當然你想傳的更大的話,可以傳form1的例項)。這樣設計的確不是一件好思路,因為這樣導致了兩個窗體類的互調,形成了極強的耦合。有什麼辦法可以減少這種耦合嗎?這時委託就發揮作用了。我們仍然將form2的例項作為form1的成員變數,並通過呼叫該變數的函式,由datagrid控制mapcontrol,但是我們並不把datagrid作為引數傳遞給form2,而是在form2種定義乙個共有委託例項,並在new form2(在form1中new的)的時候把這個委託例項初始化,即繫結到form2裡的乙個方法上,然後在form2中進行呼叫。方法如下:
類form1的設計:
public class form1
}類form2的設計
public delegate void delegatecontrol(string str);
public class form2
}這樣,在使用的時候,可以在form1直接通過成員frmmapcontrol的方法controlmapcontrol()來控制feature隨著datagrid不同的行進行高亮顯示,也可以通過在form2中用**直接呼叫form1裡的controldatagrid()函式對datagrid的游標位置進行控制。
這樣設計的好處就是form2不用使用form1中的任何東西作引數進行初始化,減少了兩個類之間的耦合。但是為了使得委託能夠繫結到form1中的方法,form2的例項還是必須作為form1 的成員。還有乙個主意的地方是,**的宣告和初始化,不能在乙個類裡面,否則跟直接呼叫函式就沒什麼不同的了。
這個事情體現出**的乙個好處:減少類之間引數傳遞,減少耦合程度。
使用委託來減少if else判斷
上述 根據傳進來的語言列舉值和名字串來輸出相應語言的問候語,不過,這個方法的可擴充套件性太差了,如果以後我們需要再新增韓文版,日文版,就不得不反覆修改列舉和dowork 方法,以適應新的需求。使用委託可以解決優化此類問題。using system using system.collections.g...
使用委託來減少if else判斷
using system using system.collections.generic using system.linq using system.text namespace 13 public void sayenglish string name public enum language...
委託的使用
using system using system.collections.generic using system.text namespace delegate private static void chinesegreeting string name 注意此方法,它接受乙個greeting...