skalb skalb - 1 month ago 11
C# Question

Cannot use ref or out parameter in lambda expressions

Why can't you use a ref or out parameter in a lambda expression?

I came across the error today and found a workaround but I was still curious why this is a compile-time error.

Here's a simple example:

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();
}

Answer

Lambdas have the appearance of changing the lifetime of variables that they capture. For instance the following lambda expression causes the parameter p1 to live longer than the current method frame as its value can be accessed after the method frame is no longer on the stack

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

Another property of captured variables is that changes to the variable are also visible outside the lambda expression. For example the following prints 42

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

These two properties produce a certain set of effects which fly in the face of a ref parameter in the following ways

  • ref parameters may have a fixed lifetime. Consider passing a local variable as a ref parameter to a function.
  • Side effects in the lambda would need to be visible on the ref parameter itself. Both within the method and in the caller.

These are somewhat incompatible properties and are one of the reasons they are disallowed in lambda expressions.

Comments