1. ホーム
  2. c#

[解決済み] ラムダ式でrefやoutパラメータを使用できない

2022-04-19 11:16:49

質問

ラムダ式でrefやoutパラメータを使用できないのはなぜですか?

今日、このエラーに遭遇し、回避策を見つけたのですが、なぜこれがコンパイル時のエラーなのか、やはり気になりました。

CS1628 : 無名メソッド、ラムダ式、またはクエリ式の内部で、in ref または out パラメータ 'parameter' を使用できない。

簡単な例を挙げます。

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

解決方法は?

ラムダは、捕捉した変数のライフタイムを変化させるという性質を持っています。 例えば、以下のラムダ式は、パラメータp1を 生きる メソッドフレームがスタック上になくなった後でもその値にアクセスできるため、現在のメソッドフレームよりも長い時間、メソッドフレームにアクセスすることができます。

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

キャプチャされた変数のもう一つの特性は、変数への変更がラムダ式の外でも見えることである。 たとえば、次のように表示されます。

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

この2つのプロパティは、以下のようにrefパラメータと相反するある種の効果を生み出します。

  • refパラメータが固定寿命を持つ場合がある。 ローカル変数を関数に ref パラメータとして渡すことを考えてみましょう。
  • ラムダでの副作用は、refパラメータ自体で確認する必要があります。 メソッド内と呼び出し側の両方で。

これらはやや相容れない性質であり、ラムダ式で禁止されている理由の一つである。