C# 匿名方法
C# 2.0 引入匿名方法,在 C# 3.0 及更高版本中,Lambda 表达式取代匿名方法作为编写内联代码的首选方式。 但是,本主题中有关匿名方法的信息也适用于 Lambda 表达式。 在有一种情况下,匿名方法提供 Lambda 表达式中没有的功能。 ==使用匿名方法可省略参数列表==。 ==这意味着匿名方法可转换为具有多种签名的委托==。 Lambda 表达式无法实现这一点。
创建匿名方法实际上是一种将代码块作为委托参数传递的方式。 这里是两个示例:
// Create a handler for a click event.
button1.Click += delegate(System.Object o, System.EventArgs e)
{ System.Windows.Forms.MessageBox.Show("Click!"); };
// Create a delegate.
delegate void Del(int x);
// Instantiate the delegate using an anonymous method.
Del d = delegate(int k) { /* ... */ };
由于使用匿名方法无需创建单独的方法,因此可减少对委托进行实例化的编码开销。
例如,在因不得不创建方法而可能出现非必要开销的情况下,指定代码块(而不是委托)很有用处。 开始新线程就是一个很好的示例。 此类创建一个线程,且还包含该线程执行的代码,而无需为委托创建其他方法。
void StartThread()
{
System.Threading.Thread t1 = new System.Threading.Thread
(delegate()
{
System.Console.Write("Hello, ");
System.Console.WriteLine("World!");
});
t1.Start();
}
备注
==匿名方法的参数范围为匿名方法块。==
如果目标在匿名方法块之外,匿名方法块内具有 goto、break 或 continue 等跳转语句是一种错误。 如果目标在匿名方法块之内,匿名方法块外具有 goto
、break
或 continue
等跳转语句也是一种错误。
范围包含匿名方法声明的本地变量和参数称为此匿名方法的外部变量。 例如,在如下代码段中,n
是一个外部变量:
int n = 0;
Del d = delegate() { System.Console.WriteLine("Copy #:{0}", ++n); };
==创建委托时,对外部变量 n
的引用被视为已捕获。 不同于本地变量,已捕获的变量的生存期一直延伸至引用匿名方法的委托具有垃圾回收资格为止。==
匿名方法无法访问外部范围的 in、ref 或 out 参数。
无法在匿名方法块内访问任何不安全代码。
不允许在 is 运算符左侧使用匿名方法。
示例
for (int i = 0; i < mToggles.Length; i++) {
var index = i;//需要将index暂存起来
mToggles[i].onValueChanged.AddListener(
delegate
{
if (mToggles[index].isOn) {
SwitchDifficulty(index);
}
});
}