與命名方法相同,匿名方法也可作為參數傳遞給函數。雖非常見用法,但未來必有需求。下列代碼展示將匿名方法與命名方法均傳遞給 Passit 函數:
#region Passing anonymous methods - Example5
private delegate void Example5(string firstName, string lastName);
private void btnExample5_Click(object sender, EventArgs e)
{
// 傳遞匿名方法
Passit((Example5)delegate(string firstName, string lastName)
{
MessageBox.Show("Example5: " + firstName + " " + lastName);
});
// 傳遞命名方法
Passit(Example5NamedMethod);
}
private void Example5NamedMethod(string firstName, string lastName)
{
MessageBox.Show("Example5Method: " + firstName + " " + lastName);
}
private void Passit(Example5 example)
{
example("Zach", "Smith");
}
#endregion
此例擴展了變量作用域,展示匿名方法能在代碼塊外執行命名方法:
#region Accessing class members - Example6
private delegate void Example6();
private int _customerId;
private string _customerCode;
public int CustomerID { get { return _customerId; } set { _customerId = value; } }
public string CustomerCode { get { return _customerCode; } set { _customerCode = value; } }
private void btnExample6_Click(object sender, EventArgs e)
{
this.CustomerID = 90;
this.CustomerCode = "1337HK";
Example6 example = new Example6(delegate
{
this.ShowCustomer(this.CustomerID, this.CustomerCode);
});
example();
this.CustomerID = 54;
this.CustomerCode = "L4M3";
example(); // 輸出新值
}
private void ShowCustomer(int customerId, string customerCode)
{
MessageBox.Show(String.Format("CustomerID: {0}\nCustomer Code: {1}", customerId, customerCode));
}
#endregion
注意:委托被調用兩次,輸出不同值。原因在於匿名方法捕獲的是變量的引用而非值,故外部修改會反映在後續調用中。另一細節:無參數時,delegate 後的括號可省略。
匿名方法雖非革命性創新,卻是 C# 邁向更友好語言的關鍵一步。