Kategorien: Alle - 方法

von 余小章 's Vor 7 Jahren

820

C# 委派

C#中的委派是一種強大的功能,類似於C++中的函式指標,可以將方法作為參數傳遞。委派在C#中實現了命令模式,這是一種設計模式,通過物件來代表實際行動,並封裝行動及其參數,使行動可以被多次重複、取消或重做。從C# 1.0到C# 3.0,委派功能得到了不斷的改進。C# 2.0引入了匿名方法,使得方法體不需要具名,並且可以直接指派給委派。而C# 3.0更進一步引入了Lambda表達式,大大簡化了代碼的可讀性和可維護性。

C# 委派

C# 委派

Command Pattern?

我們用範例來瞭解委派的用法,虛擬世界的範例Sample:SimpleDefaultDelegate

泛型委派 generic delegate

內建的泛型委派型別
Predicate

Predicate 就是:一個委派,需傳入一個參數型別為 T ,回傳值型別為 bool 。

public delegate bool Predicate(T obj);

Action

沒有回傳值,預設支援16個參數

Func

有回傳值,預設支援16個參數,最後一個TResult是回值的型態

自行定義泛型委派

為什麼要用委派?

從C#1.0~C#3.0
C#3.0實作

Lambda

Action Lambda (input parameters) => {expression}

若參數只有一個,()可以省略,如下列範例所示: x => y.Length > x

匿名方法若只有一行,{}可以省略,下列範例所示: (x,y) => y.Length > y

{}內要寫要做的事,如下列範例所示: (x,y) => {y.Length > x;}

例如:Action

Func Lambda (input parameters) => {expression:return result}

Func<int, string, bool> funcLambda = (x, y) => { return y.Length > x; };

bool result = funcLambda.Invoke(1, "123456");

under line是合法的變數命名規則,因為 Lambda 讓以下代碼看起來在開玩笑 _ => y <= _

若參數只有一個,()可以省略,如下列範例所示: x => y.Length > x

匿名方法若只有一行,{}可以省略,return可以省略,如下列範例所示: (x,y) => y.Length > y

{}內要寫要做的事並有回傳值,如下列範例所示: (x,y) => {return y.Length > x;}

例如:Func

由委派 delegate 演變而來

C#3.0,不需要使用delegate,把它換成 (input parameters) => {expression}

Func<int, string, bool> funcLambda = (x, y) => { return y.Length > x; };

bool result = funcLambda.Invoke(1, "123456");

MessageBox.Show(result.ToString());

=>右邊,代表匿名方法的內容。

=>左邊,代表匿名方法的參數。

=>,代表這是個匿名方法。可以想像成宣告為delegate的匿名方法。意義是goes to,也就是把=>左邊的參數,交給=>右邊的運算式或陳述式執行。

方法體只有一行時 {} 可以省略

{} 方法體,方法要處理的內容

參數只有一個時()可以省略

() 方法的參數

Sample:SimpleLambda

C#2.0實作

實體化 delegate,不需要用new,直接將方法體指派給 delegate

方法體不需具名(匿名方法)

可以不需要定義 delegate 簽章

C#1.0實作

一個Invoke可觸動多個動作

若需要多個動作則註冊+=,反之調用-=

調用Invoke

實體化時將方法體傳入 delegate 建構函式

定義方法

定義delegate簽章

C#1.0,定義 Delegate 和 Method,兩者都要具名定義,簽章(參數)也要相同

Sample:SimpleDefaultDelegate
最常見的場景,多執行緒非同步開發、LINQ

甚麼是委派?

它實作了 Command Pattern
命令模式是一種設計模式,它嘗試以物件來代表實際行動。命令物件可以把行動(action) 及其參數封裝起來,於是這些行動可以被:

取消後又再重做

取消(如果該物件有實作的話)

重複多次

像是C++裡面的函示指標
把方法當參數傳遞出去

它不能吃,這是肯定的

搞的懂它在幹嘛的請舉手