是否存在委托语法优先于匿名方法的lambda表达式的情况?
随着lambda表达式(内联代码)等新function的出现,它是否意味着我们不再需要使用委托或匿名方法了? 在我看过的几乎所有样本中,都是使用新语法进行重写。
我们仍然需要使用delegates和lambda表达式的任何地方都不起作用?
是的,有些地方直接使用匿名委托,lambda表达式不起作用。
如果某个方法采用无类型的Delegate,那么编译器不知道要解析匿名委托/ lambda表达式的内容,您将收到编译器错误。
public static void Invoke(Delegate d) { d.DynamicInvoke(); } static void Main(string[] args) { // fails Invoke(() => Console.WriteLine("Test")); // works Invoke(new Action(() => Console.WriteLine("Test"))); Console.ReadKey(); }
失败的代码行将得到编译器错误“无法将lambda表达式转换为类型’System.Delegate’,因为它不是委托类型”。
lambda是匿名委托的快捷方式,但您将始终使用委托。 委托指定方法签名。 你可以这样做:
delegate(int i) { Console.WriteLine(i.ToString()) }
可以替换为
f => Console.WriteLine(f.ToString())
Lambda表达式不是(并不意味着)一个替代(隐藏)代表的银弹。 当地的小东西很棒,比如:
List names = GetNames(); names.ForEach(Console.WriteLine);
- 它使代码更易读,因此易于理解。
- 它使代码更短,因此对我们来说工作量减少;)
另一方面,滥用它们非常简单。 长或/和复杂的lambda表达式倾向于:
- 新开发人员很难理解
- 面向对象较少
- 更难阅读
所以“这是否意味着我们不再需要使用委托或匿名方法?”否 – 使用Lambda表达式,您可以在其中赢得时间/可读性,否则请考虑使用委托。
Lambda表达式只是“语法糖”,编译器将为您生成适当的委托。 您可以使用Lutz Roeder的Reflector进行调查。
Lamda只是代表们的语法糖,他们不只是内联,你可以做到以下几点:
s.Find(a => { if (a.StartsWith("H")) return a.Equals("HI"); else return !a.Equals("FOO"); });
并且在定义事件时,或者当您有大量参数并希望实际强类型化被调用的方法时,仍会使用委托。
代表在C#中有两个含义。
关键字delegate
可用于定义函数签名类型。 这通常在定义高阶函数的签名时使用,即将其他函数作为参数的函数。 代表的这种使用仍然相关。
delegate
关键字也可用于定义内联匿名函数。 在函数只是单个表达式的情况下,lambda语法是一种更简单的替代方法。
旧delegate
语法的一个不那么大的优点是,如果您不在方法体中使用它,则无需指定参数。 来自msdn
有一种情况是匿名方法提供lambda表达式中没有的function。 匿名方法使您可以省略参数列表。 这意味着可以将匿名方法转换为具有各种签名的委托。 lambda表达式无法做到这一点。
例如,你可以这样做:
Action a = delegate { }; //takes 1 argument, but not specified on the RHS
虽然这失败了:
Action a = => { }; //omitted parameter, doesnt compile.
在编写事件处理程序时,这种技术通常很方便,例如:
button.onClicked += delegate { Console.WriteLine("clicked"); };
这不是一个强大的优势。 最好采用新的语法总是imho。
- C#Numeric Only TextBox控件
- System.Windows.Controls.TextBox句柄
- 即使pagesize设置为更大,directorysearcher对象的上限是5000
- System.IO.Exception:管道已损坏
- 使用try catch返回yield,我该如何解决它
- 按一些标准从集合中选择最大项目
- 与SAM一起使用System.DirectoryServices.AccountManagement.PrincipalContext.ValidateCredentials时出现奇怪错误
- 在运行时动态创建函数
- bool作为CheckBox的数据源(Bool更新在另一个线程中而不是它正在影响的线程)