zz from WebCast—C#2.0銳利體驗
1. 匿名方法簡介
匿名方法允許我們以一種“內聯”的方式來編寫方法代碼,將代碼直接與委託實例相關聯,從而使得委託實例化的工作更加直觀和方便。
2.匿名方法的幾個相關問題:
2.1 參數列表
匿名方法可以在delegate關鍵字後跟一個參數列表(可以不指定),後面的代碼塊則可以訪問這些參數:
addButton.Click += delegate(object sender, EventArgs e) {MessageBox.Show(((Button)sender).Text);};
注意“不指定參數列表”與“參數列表爲空”的區別
addButton.Click += delegate {…} // 正確!
addButton.Click += delegate() {…} // 錯誤!
2.2 返回值
如果委託類型的返回值類型爲void,匿名方法裏便不能返回任何值;如果委託類型的返回值類型不爲void,匿名方法裏返回的值必須和委
託類型的返回值兼容:
delegate int MyDelegate();
MyDelegate d = delegate{
……
return 100;
};
delegate void MyDelegate();
MyDelegate d = delegate{
……
return;
};
2.3 外部變量
一些局部變量和參數有可能被匿名方法所使用,它們被稱爲“匿名方法的外部變量”。外部變量的生存期會由於“匿名方法的捕獲效益”而延長——一直延長到委託實例不被引用爲止。
static void Foo(double factor) {
Function f=delegate(int x) {
factor +=0. 2; // factor爲外部變量
return x * factor;
};
Invoke(f); // factor的生存期被延長
}
3.委託類型的推斷
C#2.0 允許我們在進行委託實例化時,省略掉委託類型,而直接採用方法名,C#編譯器會做合理的推斷。
• C# 1.0中的做法:
addButton.Click += new EventHandler(AddClick);
Apply(a, new Function(Math.Sin));
• C# 2.0中的做法:
addButton.Click += AddClick;
Apply(a, Math.Sin);
4 匿名方法機制
C# 2.0中的匿名方法僅僅是通過編譯器的一層額外處理,來簡化委託實例化的工作。它與C# 1.0的代碼不存在根本性的差別。
4.1 靜態方法中的匿名方法
public delegate void D();
static void F() {
D d = delegate { Console.WriteLine("test"); }
}
上面的代碼被編譯器轉換爲:
static void F() {
D d = new D(<F>b__0);
}
static void <F>b__0() { //函數名和類名可能不同
Console.WriteLine("test");
}
4.2 實例方法中的匿名方法
class Test {
int x;
void F() {
D d = delegate { Console.WriteLine(this.x); };
}
}
上面的代碼被編譯器轉換爲:
void F() {
D d = new D(<F>b__0);
}
void <F>b__0() {
Console.WriteLine(this.x);
}
4.3 匿名方法中的外部變量
void F() {
int y = 123;
D d = delegate { Console.WriteLine(y); };
}