明确赋值
对匿名方法参数的明确赋值规则和命名方法(named method,区别于匿名方法)参数的明确复制规定一样。也就是说,引用参数和值参数必须同国明确的赋值进行初始化,而输出参数可以不比进行明确赋值。
另外,如果要在匿名方法正常返回之前使用输出参数,则输出参数必须被明确赋值。
当控制转移到匿名方法表达式的块中时,对于一个外部变量v的明确赋值规定与匿名方法表达式之前对v的明确赋值规定一样。
对于一个匿名方法后面的变量v的明确赋值规定和匿名方法表达式之前的明确赋值规定相同。
下面的例子:
delegate bool Filter(int i);
void F() {
int max;
// 错误,max没有被明确赋值
Filter f = delegate(int n) { return n < max; }
max = 5;
DoWork(f);
}
会产生一个编译错误,因为在匿名方法声明之前max没有被明确赋值。下面的例子
delegate void D();
void F() {
int n;
D d = delegate { n = 1; };
d();
// 错误,n没有被明确赋值
Console.WriteLine(n);
}
同样会产生变异错误,因为匿名方法中对n的赋值不会影响匿名方法外部对n的明确赋值。
方法组转换
和匿名方法转换节中描述的匿名方法隐式转换类似,从一个方法组到一个兼容的委托类型之间也存在一个隐式的转换。
对于一个给定的方法组E和一个委托类型D,如果允许形为new D(E)的委托建立表达式,则存在E到D的隐式转换,
下面的例子:
using System;
using System.Windows.Forms;
class AlertDialog {
Label message = new Label();
Button okButton = new Button();
Button cancelButton = new Button();`
public AlertDialog() {
okButton.Click += new EventHandler(OkClick);
cancelButton.Click += new EventHandler(CancelClick);
...
}
void OkClick(object sender, EventArgs e) {
...
}
void CancelClick(object sender, EventArgs e) {
...
}
}
构造器使用两个new运算符建立了两个委托实例。隐式方法组转换允许将其写作更短的形式:
public AlertDialog() {
okButton.Click += OkClick;
cancelButton.Click += CancelClick;
...
}
与其它隐式和显式转换相同,转换运算符可以显式地用于一个特定的转换中。因此,下面的例子:
object obj = new EventHandler(myDialog.OkClick);
可以写作:
object obj = (EventHandler)myDialog.OkClick;
方法组和匿名方法表达式会影响到重载抉择,但不会参与类型推断。