当使用lambda表达式作为参数(如
Enumerable.Where)的方法被调用而不在表达式中实际声明变量或方法参数时,会调用什么?
例如,我熟悉这个lambda表达式语法:
public string GetDigits(string input) { return new String(input.Where(i => Char.IsDigit(i)).ToArray()); }
不过,我对find out感到惊讶,这也可以写成:
public string GetDigits(string input) { return new String(input.Where(Char.IsDigit).ToArray()); }
解决方法
方法不接受lambdas作为参数.他们接受委托作为参数. lambda只是创建委托的一种方式.
另一种方法是提供一个方法组,就像在第二个例子中所做的那样,它可以转换成一个委托.
类似的方法是使用匿名方法功能.这些或多或少被替换为羊羔,当他们加入,所以你看不到太多.您使用该语法的示例将是:
Func<char,bool> predicate = delegate(char c) { return Char.IsDigit(c); };
另一种方法是使用Delegate.CreateDelegate创建一个委托. (这不是你经常看到的东西.)
最后一个方法是从其他地方获得一个委托变量. (其他地方将使用其他选项之一创建代表.)
What’s going on in that second snippet,where the Char.IsDigit() method is (apparently) being called with an implicit parameter? What is this Syntax called?
它没有被叫.这就是全部.我们正在尝试创建一个委托.委托是一个跟踪要调用的方法的对象,以及应该调用的对象.然后,您可以调用委托,它将调用用于创建它的方法.所以在这里你不是调用IsDigit,你正在创建一个指向IsDigit方法的委托,每当调用该委托时,它将调用它.
当您使用lambda时,您将创建一个新方法,可能在一个新类中(两者都不具有可以引用的名称,但是在运行时它们将有一个),并且该匿名方法的正文将调用IsDigit .然后,lambda解析为指向该匿名方法的代理,该方法维护另一个示例的语义,该方法具有一种方法,当被调用时,调用一个匿名方法,该方法在其实现中调用IsDigit.它增加了一个额外的间接层(可能也可能不会在运行时被优化)来完成同样的事情.