C 委託之我見

2022-02-13 12:07:52 字數 3236 閱讀 8512

委託的使用方式很簡單,了解一下基本語法就可以開擼了。但是使用委託的真正難題是不知道應用場景,就像習得了一門新功夫,但是卻找不到任何施展拳腳的地方。這個難題一直困然著我,直到最近彷彿有所領悟,所以趕緊記下這可能尚不成熟的觀點。如果有什麼錯誤的想法,還望各位園友指正。

其實委託最大的作用是解耦合,轉移程式方法的功能定義方。在不使用委託的情況下,方法的功能和行為(能做的事)都是由方法提供方決定的,方法一經定義,能做的事情也就固定了,這就相當於方法是靜態的。但是如果方法使用了委託引數型別,方法功能的定義方就發生了轉移,此時方法能做什麼事是由方法的呼叫方決定的。這樣就相當於方法有了生命力,這種生命力是方法的呼叫方賦予的。並且方法的可重用性得到了提高,以前是做一件事情,現在是做一類事情。同時,委託可以看做是把方法作為方法的引數,這樣會避免掉一些不必要的判斷(因為作為引數的方法會定義做什麼事情,不用再額外判斷),簡化程式邏輯。

talk is cheap,show me the code.

我們寫程式時經常會遇到這樣一種情況。在分支判斷中,每個分支中做的操作都可以歸屬於一類事情,方法的簽名也能保持一致。這時可以考慮使用委託消除掉這些分支判斷。假設現在要做乙個四則運算的功能,其擁有四個方法,它們的簽名都相同,都接受兩個double輸入,並輸出乙個double。一般的做法是:

public enum operate

public static double calculate(double a,double b, operate operate)

}public static double add(double a , double b)

public static double subtrac(double a, double b)

public static double multip(double a, double b)

public static double divisi(double a, double b)

這樣實現有乙個缺點,現在是四則運算,萬一以後加入其它型別的運算呢?每加入乙個型別的運算都要新增乙個分支判斷,這樣的話維護成本就有點高了,也不符合對修改關閉,對擴充套件開放的開閉原則。要是為每種型別的操作建個類,用多型的思想解決又有點小題大做了。可以考慮使用委託解決這個問題,使用和方法簽名相同的委託代替列舉型別的引數。

首先新建乙個和方法簽名相同的委託型別,然後使用和方法簽名相同的委託代替列舉型別的引數:

public delegate double calculatedelegate(double a, double b);
public static double calculate(double a, double b, calculatedelegate operate)

呼叫方決定具體的運算:

static void main(string args)

利用委託來解決這種問題看似很好,但是也有缺點,需要為每一種計算型別定義相應的方法,而且其中有些方法使用頻率並不高,程式中可能會大量出現這樣的計算方法,維護這些方法反而是不小的負擔。c#提供了匿名函式的方式來解決這個問題。

static void main(string args)

); calculate(1, 1, delegate (double a, double b) );

}

嗯,解決了上面的問題。但是似乎**可讀性不夠高,那就繼續進化,c#提供了lambda表示式,讓我們以幾乎感覺不到委託存在的方式,順其自然的使用c#委託,原生c#委託幾乎被遺忘,委託三步走不復存在,委託=>匿名函式=>lambda表示式 究極進化,c#就是這麼強大!

你可以這麼玩:calculate(1, 2, (double a,double b) => );

還可以這麼玩:calculate(1, 2, (a,b) => );

c#中的linq可謂是將委託用到了極致,以where方法為例,where方法本身只負責篩選集合中的元素這類事,但是至於具體是哪件事,並不關心。具體做哪件事是由方法的呼叫方來指定的,比如篩選大於10的元素、或是小於5的元素,這些都是由呼叫方決定的。方法的靈活性、可重用性都得到了提高。設想一下,如果為每個元素篩選條件規則都去寫乙個除了篩選條件不同其他操作都相同的新方法,心態**不?使用委託型別的引數,這一切將變得很簡單。做一件事情變為做一類事情,至於是哪一件事情,方法呼叫方來決定嘍。

這種方式最重要的應用就是**函式。

**函式就是乙個通過函式指標呼叫的函式。 如果你把函式的指標(位址)作為引數傳遞給另乙個函式,當這個指標被用來呼叫其所指向的函式時,我們就說這是**函式**函式不是由該函式的實現方直接呼叫,而是在特定的事件或條件發生時由另外的一方呼叫的,用於對該事件或條件進行響應。

簡單理解,當我們將函式a傳遞給函式b,並由b來執行a時,a就成了乙個**函式(callback functions)。**函式肯定是方法呼叫方負責定義的,當方法執行時,滿足相應的條件就會觸發此**函式。在c#中實現**函式的方式就是委託。

假設現在我們有兩個方法,乙個方法負責將陣列中的每個元素翻倍,另乙個方法負責加1,現在需要翻倍再加一。如果不使用委託(**函式),則需要進行兩次for迴圈,效能上無法接受,這個時候就可以使用委託(**函式)來解決,只需要一次for迴圈就可以。

不使用委託(**函式):

public static void double(int nums)

}public static void addone(int nums)

}

static void main(string args)

; double(nums);

addone(nums);

}

使用委託(**函式):

public static void doubleandaddone(int nums,funcfunc)

}

doubleandaddone(nums, n => n + 1);

C 委託 委託概述

c 委託概述 委託這個詞在生活中經常用到,委託律師打官司,委託房地產公司購買房子。委託保險 人辦理保險。委託就是把事情交給別人去辦。c 中的委託和生活中的委託很相似,如果將乙個方法委託給乙個物件,那麼這個物件就可以全權 這個方法執行。委託宣告定義乙個類,它是從 system.delegate 類派生...

C 委託 匿名委託

c 委託 匿名委託 委託變數在繫結方法時,是把方法名賦值給了委託變數名,這 樣就需要在類裡面定義方法,而有些方法只用到了 次,這樣的 方法在類裡面過多時,程式的可讀性就不是太好,針對這種情 況,可以使用匿名委託,即不用在類裡面額外定義方法.delegate定義的匿名委託 格式 delegate 引數...

C 委託,委託鏈,多播委託

委託 概念 委託是一種使用者自定義的型別.是一種類.可以把委託看成用來執行方法 函式的乙個東西 形式 delegate 函式返回型別 委託名稱 引數部分 例項化 委託型別 例項化名 new 委託型別 方法名稱 實現 usingsystem usingsystem.collections.generi...