C 基礎 匿名方法

2021-09-05 19:56:21 字數 2854 閱讀 8664

匿名方法是c# 2.0的語言新特性。首先看個最簡單的例子:

view plaincopy to clipboardprint?

class program   

}   

static

bool namematches(string name)   

}   

這段**在開始的時候初始化了乙個字串列表(string list),然後通過列表的findall方法來查詢以「sunny」起始的字串,最後將所查詢到的所有結果輸出。

我們需要著重介紹list的findall方法。這個方法是乙個引數為predicate型別、返回值為list型別的函式。注意,predicate是乙個泛型委託,它指代這樣一些函式:這些函式僅有乙個t型別的引數,並且返回值是布林型別。通過reflector等工具,我們可以看到predicate的定義如下:

view plaincopy to clipboardprint?

public

delegate

bool predicate(t obj);   

至此我們也多少能夠猜到findall方法的具體實現。即針對list中的每個元素,呼叫predicate所指代的函式,如果函式返回為true,則將其加入新建的列表中。遍歷完所有的元素後,將新建的列表返回給呼叫者。如下:

view plaincopy to clipboardprint?

public listfindall(predicatematch)   

return ret;   

}   

因此,針對上面的例子,要呼叫findall方法,我們必須先定義乙個引數為string型別,返回值為布林型別的函式,在這個函式中,對引數進行條件判斷,如果符合條件(也就是以「sunny」作為起始字串),那麼就返回true,否則返回false。最後再將這個函式作為引數傳遞給findall。於是也就得到了最上面的**。

在上面的例子中,為了呼叫findall方法,我們不得不新定義乙個函式,其實這個函式除了findall方法要用外,別的地方都幾乎很少使用到它,你還不得不給它起個名字。如果程式中有多處需要呼叫findall方法,或者類似的情況,那麼整個程式也就會出現一大批「只有乙個地方使用」的函式,使得**難於閱讀和維護。

由於存在這樣的問題,c# 2.0引入了匿名方法。開發人員在實現方法的時候,只需要給出方法的引數列表(甚至也可以不給)以及方法具體實現,而不需要關心方法的返回值,更不必給方法起名字。最關鍵的是,只在需要的地方定義匿名方法,保證了**的簡潔。

匿名方法只在需要的地方定義,定義的時候,使用delegate關鍵字,後接引數列表,然後跟上用一對花括號包括起來的函式體即可。上面的**可以重構成下面的形式:

view plaincopy to clipboardprint?

class program   

);   

if (found != null)   

}   

//static bool namematches(string name)

// }   

此時,我們完全不需要namematches方法了,直接將匿名方法作為引數傳遞給findall方法。其實匿名方法本身還是有名字的,只是我們並不關心它究竟該取什麼名字,因而.net幫我們隨便取了個名字罷了。

匿名方法在c#中應用十分廣泛,因為委託作為函式引數是件非常平常的事情。在定義簡單的事件處理過程時,我們同樣可以使用匿名方法。比如:

view plaincopy to clipboardprint?

servicehost host = new servicehost(typeof(filetransferimpl));   

host.opened += delegate(object sender, eventargs e)   

;   

匿名方法可以很方便地使用本地變數,這與單獨定義的命名方法相比,能夠簡化程式設計。比如上文的例子中,假如main函式裡面定義了乙個整型本地變數(區域性變數)number,那麼可以在delegate (string name)這一匿名方法定義中使用number變數。

上文提到,在定義匿名方法的時候,連引數列表都可以省略。因為編譯器可以根據委託的簽名來確定函式的簽名,然後只要再給函式起個名字就可以了。下面的**演示了這種使用方式:

view plaincopy to clipboardprint?

delegate

void intdelegate(int x);   

// 帶引數的定義方式

intdelegate d2 = delegate(int p) ;   

// 不帶引數的定義方式(當然也沒帶返回值)

intdelegate d3 = delegate ;   

在使用不帶引數和返回值的匿名方法定義時,需要注意以下兩點:

如果在你的匿名方法中需要對引數進行處理,那麼你不能使用不定義引數列表的宣告方式。也就是在定義匿名方法的時候,需要給出引數列表

不帶引數和返回值的匿名方法,可以被具有任何形式簽名的委託所指代

上述第一點顯而易見,因為你沒有定義引數列表,也就沒有辦法使用引數;要說明第二點,我們可以看下面的**:

view plaincopy to clipboardprint?

class program   

static

void output(stringdelegate sd)   

static

void main(string args)   

);   

}   

}   

上面的**沒法編譯通過,因為編譯器不知道應該將delegate 這一匿名方法還原為由intdelegate指代的函式,還是還原為由stringdelegate指代的函式。此時只能顯式給定引數列表,以便讓編譯器知道,我們究竟是想呼叫哪個output函式。

c 匿名方法用途 C 匿名方法

我們討論了使用委託來引用具有與委託相同簽名的任何方法。換句話說,您可以使用該委託物件呼叫可由委託引用的方法。匿名方法提供了一種將 塊作為委託引數傳遞的技術。匿名方法是沒有名稱的方法,只是主體。您無需在匿名方法中指定返回型別 它是從方法體內的return語句推斷出來的。編寫匿名方法 匿名方法是通過建立...

c 匿名方法用途 C 匿名方法

c 語言 的 c 匿名方法 前面我們學習過,委託可用於引用任何與委託簽名相同的方法。換句話說,可以呼叫可以由委託使用該委託物件引用的方法。匿名方法提供了一種將 塊作為委託引數傳遞的技術。匿名方法是沒有名稱的方法,只有方法體。不需要在匿名方法中指定返回型別 它是從方法體中的return語句來推斷的。編...

C 匿名方法

1,匿名方法 c 為委託提供一種機制,可以為委託定義匿名方法,匿名方法沒有名稱,編譯器會定指定乙個名稱 匿名方法中不能使用跳轉語句跳轉到該匿名方法的外部,也不能跳轉到該方法的內部。也不能在匿名方法外部使用的ref和out引數 2,匿名方法的 拉姆達 表示式 方式定義 c 3.0之後匿名方法可以使用 ...