代码之家  ›  专栏  ›  技术社区  ›  skalb

不能在lambda表达式中使用ref或out参数

  •  209
  • skalb  · 技术社区  · 17 年前

    为什么不能在lambda表达式中使用ref或out参数?

    我今天遇到了这个错误,并找到了一个解决方法,但我仍然很好奇为什么这是一个编译时错误。

    CS1628

    这里有一个简单的例子:

    private void Foo()
    {
        int value;
        Bar(out value);
    }
    
    private void Bar(out int value)
    {
        value = 3;
        int[] array = { 1, 2, 3, 4, 5 };
        int newValue = array.Where(a => a == value).First();
    }
    
    6 回复  |  直到 8 年前
        1
  •  129
  •   silkfire thezar    10 年前

    Lambda的外观是改变它们捕获的变量的生命周期。例如,以下lambda表达式导致参数p1 比当前方法帧长,因为可以在方法帧不再在堆栈上后访问其值

    Func<int> Example(int p1) {
      return () => p1;
    }
    

    void Example2(int p1) {
      Action del = () => { p1 = 42; };
      del();
      Console.WriteLine(p1);
    }
    

    ref

    • 参考 参考
    • lambda中的副作用需要在 参考 参数本身。在方法和调用者中。

    这些属性有些不兼容,是lambda表达式中不允许使用它们的原因之一。

        2
  •  87
  •   marsze    6 年前

    (这就是你的问题正文的全部内容)并将它们存储为编译器生成类的字段。没有办法存储 ref out 参数作为字段。Eric Lippert在 a blog entry

    delegate void TestDelegate (out int x);
    static void Main(string[] args)
    {
        TestDelegate testDel = (out int x) => { x = 10; };
        int p;
        testDel(out p);
        Console.WriteLine(p);
    }
    
        3
  •  74
  •   Ben Adams    9 年前

    您可以但必须明确定义 全部 类型如此

    (a, b, c, ref d) => {...}
    

    (int a, int b, int c, ref int d) => {...}
    

        4
  •  5
  •   Jonathan Dickinson    15 年前

    private void Foo()
    {
        int value;
        Bar(out value);
    }
    
    private void Bar(out int value)
    {
        value = 3;
        int[] array = { 1, 2, 3, 4, 5 };
        var val = value; 
        int newValue = array.Where(a => a == val).First();
    }
    
        5
  •  2
  •   nl-x    6 年前

    不能在lambda表达式中直接使用out参数。其他答案中解释了你不能这样做的原因。

    但是,您可以为内部函数使用一个局部临时变量,并在执行内部函数后,将内部函数的out值赋值给外部函数的out:
    private static int OuterFunc (int i_param1, out int o_param2)
    {
      int param2 = 0;
      var del    = () => InnerFunc (i_param1, out param2);
      int result = del ();
    
      o_param2 = param2;
      return result;
    }
    
    private static int InnerFunc (int i_param1, out int o_param2)
    {
      o_param2 = i_param1;
      return i_param1;
    }
    
    private static void Main (string[] args)
    {
      int result = OuterFunc (123, out int param2);
      Console.WriteLine (result);  // prints '123'
      Console.WriteLine (param2);  // prints '123'
    }