【问题标题】:C# scoping operatorC# 范围运算符
【发布时间】:2011-01-21 06:18:01
【问题描述】:

回到学校,我们编写了一个编译器,其中花括号具有执行所有表达式并返回最后一个值的默认行为......所以你可以编写如下内容:

int foo = { printf("bar"); 1 };

在 C# 中有没有等价的东西?例如,如果我想编写一个有副作用的 lambda 函数。

关于 lambda 副作用(只是一个示例)的重点较少,如果有此功能则更多...例如在 lisp 中,您有 progn

【问题讨论】:

    标签: c# scope curly-braces


    【解决方案1】:
    int foo = (() => { printf("bar"); return 1; })();
    

    编辑:感谢建设性的批评,应该是

    int i = ((Func<int>)(() => { printf("bar"); return 1; }))();
    

    【讨论】:

    • 这是正确的答案——也就是说,认真考虑不要这样做。
    • 你们可能想在投票之前检查代码是否编译。这没有。 -1.
    • 是的,是的,printf 在 C# 中不存在。但答案并非如此。
    • 这与缺少printf 函数无关。把它改成Console.WriteLine,你还是会得到一个编译错误,“Method name expected”。
    • 可能过于冗长,但是应该编译的int foo = ((Func&lt;int&gt;)(() =&gt; { Console.WriteLine("bar"); return 1; }))(); 怎么样?
    【解决方案2】:

    我们考虑过使用比 ()=&gt;{M();} 更简洁的语法来定义 lambda,但实际上并没有设法找到一种既可读性好又不易与块、集合/对象初始化程序混淆的语法,或数组初始值设定项。你现在被 lambda 语法困住了。

    【讨论】:

      【解决方案3】:

      原则上,Vlad 的回答是正确的,不需要提前将 lambda 函数声明为委托。

      不过,情况在 C# 中并不那么简单,因为编译器无法决定是否应该将语法 lambda 表达式编译为委托(例如 Func&lt;int&gt;)或表达式树(例如 Expression&lt;Func&lt;int&gt;&gt;),而且它可以是任何其他兼容的委托类型。因此,您需要创建委托:

      int foo = new Func<int>(() => { 
        Console.WriteLine("bar"); return 1; })(); 
      

      您可以通过定义一个简单地返回委托然后调用该方法的方法来稍微简化代码 - C# 编译器将自动推断委托类型:

      static Func<R> Scope<R>(Func<R> f) { return f; }
      
      // Compiler automatically compiles lambda function
      // as delegate and infers the type arguments of 'Scope'
      int foo = Scope(() => { Console.WriteLine("bar"); return 1; })(); 
      

      我同意这是一个不应该使用的丑陋技巧 :-),但有趣的事实是它可以做到!

      【讨论】:

        【解决方案4】:

        你说的是匿名函数:http://msdn.microsoft.com/en-us/library/bb882516.aspx,我想。

        【讨论】:

          【解决方案5】:

          没有什么能阻止你在 lambda 表达式中产生副作用。

          Func<int> expr = () =>
          {
              Console.WriteLine("bar");
              return 1;
          };
          int foo = expr();
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-06-09
            • 2011-07-28
            • 1970-01-01
            • 1970-01-01
            • 2012-04-20
            • 1970-01-01
            相关资源
            最近更新 更多