jjzjj

没有变量/参数声明的 C# lambda 表达式?

coder 2024-05-31 原文

当一个方法以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());
}

在第二个代码段中发生了什么,其中 Char.IsDigit() 方法(显然)是使用隐式参数调用的?这个语法叫什么?

最佳答案

方法不接受lambdas 作为参数。他们接受委托(delegate)作为参数。 lambda 只是创建委托(delegate)的一种方式。

另一种方法是提供一个方法组,就像在您的第二个示例中所做的那样,它可以转换为委托(delegate)。

类似的方法是使用匿名方法特性。不过,在添加它们时,它或多或少地被 lambdas 取代了,所以你看不到它。您使用该语法的示例是:

Func<char, bool> predicate = delegate(char c) { return Char.IsDigit(c); };

另一种方法是使用 Delegate.CreateDelegate 创建委托(delegate)。 (虽然这不是您经常看到的东西。)

最后一种方法是使用从其他地方获得的委托(delegate)变量。 (其他地方会使用这些其他选项之一创建委托(delegate)。)

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?

没有被调用。这就是重点。我们正在尝试创建一个委托(delegate)。委托(delegate)是一个对象,它跟踪要调用的方法,以及应该调用它的对象。然后您可以调用该委托(delegate),它将调用用于创建它的方法。所以这里您不是调用IsDigit,您正在创建一个指向IsDigit 方法的委托(delegate),它会在任何时候调用它该委托(delegate)被调用。

当您使用 lambda 时,您正在创建一个新方法,可能在一个新类中,(它们都没有可以引用的名称,但它们在运行时会有一个)和该匿名方法的主体将调用 IsDigit。然后,lambda 解析为指向该匿名方法的委托(delegate),该委托(delegate)维护另一个示例的语义,即在调用时调用匿名方法的方法,在其实现中调用 IsDigit。它添加了一个额外的间接层(可能会或可能不会在运行时优化)来完成同样的事情。

关于没有变量/参数声明的 C# lambda 表达式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30895055/

有关没有变量/参数声明的 C# lambda 表达式?的更多相关文章

  1. ruby - 难道Lua没有和Ruby的method_missing相媲美的东西吗? - 2

    我好像记得Lua有类似Ruby的method_missing的东西。还是我记错了? 最佳答案 表的metatable的__index和__newindex可以用于与Ruby的method_missing相同的效果。 关于ruby-难道Lua没有和Ruby的method_missing相媲美的东西吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/7732154/

  2. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

    exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

  3. ruby-on-rails - rails 目前在重启后没有安装 - 2

    我有一个奇怪的问题:我在rvm上安装了ruby​​onrails。一切正常,我可以创建项目。但是在我输入“railsnew”时重新启动后,我有“程序'rails'当前未安装。”。SystemUbuntu12.04ruby-v"1.9.3p194"gemlistactionmailer(3.2.5)actionpack(3.2.5)activemodel(3.2.5)activerecord(3.2.5)activeresource(3.2.5)activesupport(3.2.5)arel(3.0.2)builder(3.0.0)bundler(1.1.4)coffee-rails(

  4. ruby-on-rails - 如何使用 instance_variable_set 正确设置实例变量? - 2

    我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击

  5. ruby 正则表达式 - 如何替换字符串中匹配项的第 n 个实例 - 2

    在我的应用程序中,我需要能够找到所有数字子字符串,然后扫描每个子字符串,找到第一个匹配范围(例如5到15之间)的子字符串,并将该实例替换为另一个字符串“X”。我的测试字符串s="1foo100bar10gee1"我的初始模式是1个或多个数字的任何字符串,例如,re=Regexp.new(/\d+/)matches=s.scan(re)给出["1","100","10","1"]如果我想用“X”替换第N个匹配项,并且只替换第N个匹配项,我该怎么做?例如,如果我想替换第三个匹配项“10”(匹配项[2]),我不能只说s[matches[2]]="X"因为它做了两次替换“1fooX0barXg

  6. ruby - RSpec - 使用测试替身作为 block 参数 - 2

    我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere

  7. ruby - 通过 ruby​​ 进程共享变量 - 2

    我正在编写一个gem,我必须在其中fork两个启动两个webrick服务器的进程。我想通过基类的类方法启动这个服务器,因为应该只有这两个服务器在运行,而不是多个。在运行时,我想调用这两个服务器上的一些方法来更改变量。我的问题是,我无法通过基类的类方法访问fork的实例变量。此外,我不能在我的基类中使用线程,因为在幕后我正在使用另一个不是线程安全的库。所以我必须将每个服务器派生到它自己的进程。我用类变量试过了,比如@@server。但是当我试图通过基类访问这个变量时,它是nil。我读到在Ruby中不可能在分支之间共享类变量,对吗?那么,还有其他解决办法吗?我考虑过使用单例,但我不确定这是

  8. ruby-on-rails - active_admin 目录中的常量警告重新声明 - 2

    我正在使用active_admin,我在Rails3应用程序的应用程序中有一个目录管理,其中包含模型和页面的声明。时不时地我也有一个类,当那个类有一个常量时,就像这样:classFooBAR="bar"end然后,我在每个必须在我的Rails应用程序中重新加载一些代码的请求中收到此警告:/Users/pupeno/helloworld/app/admin/billing.rb:12:warning:alreadyinitializedconstantBAR知道发生了什么以及如何避免这些警告吗? 最佳答案 在纯Ruby中:classA

  9. ruby - 如何在 Ruby 中拆分参数字符串 Bash 样式? - 2

    我正在为一个项目制作一个简单的shell,我希望像在Bash中一样解析参数字符串。foobar"helloworld"fooz应该变成:["foo","bar","helloworld","fooz"]等等。到目前为止,我一直在使用CSV::parse_line,将列分隔符设置为""和.compact输出。问题是我现在必须选择是要支持单引号还是双引号。CSV不支持超过一个分隔符。Python有一个名为shlex的模块:>>>shlex.split("Test'helloworld'foo")['Test','helloworld','foo']>>>shlex.split('Test"

  10. ruby - 在没有 sass 引擎的情况下使用 sass 颜色函数 - 2

    我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re

随机推荐