8

次のようなLINQクエリがあります。

public IEnumerable<Foo> SelectFooBars()
{
    return
        from
            f in foos
        join
            b in bars
            on f.BarId equals b.Id
        select
            AddMissingProp(f, b.MissingProp);
}

public void AddMissingProp(Foo foo, string missingProp) // substitute this with inline lambda
{
    foo.MissingProp = missingProp;
    return foo;
}

代わりに、句AddMissingPropでラムダの形式を削除して使用したいと思います。select

私は試みました...

...
select
    (f, b) => { f.MissingProp = b.MissingProp; return f }

...しかし、次のエラーが発生しました:

'f'という名前のローカル変数は、'f'とは異なる意味を与えるため、このスコープでは宣言できません。これは、'親または現在の'スコープで他の何かを示すためにすでに使用されています。

クエリを「ラムダ化」するにはどうすればよいですか?


アップデート

これも機能しません:

...
select
    () => { f.MissingProp = b.MissingProp; return f }

次のエラーが発生します。

join句の式の1つの型が正しくありません。'Join'の呼び出しで型推論が失敗しました。

条項をまったく変更しなかったjoinので、困惑しています。

4

5 に答える 5

5

私はicambronが正しいと思います、私見より読みやすいバージョンはこれです:

  var fooBar = from 
                 f in foos
               join 
                 b in bars
                 on f.BarId equals b.Id 
               select new {f,b};

   foreach(var x in fooBar)
        x.f.MissingProp = x.b.MissingProp;

   // EDIT due to comments: add this if you 
   // need IEnumerable<Foo> returned
   return fooBar.Select(fb => fb.f);

ステートメントはfrom join selectクエリ用であり、シーケンスの内容を変更するために誤用しないでください。

編集:これは、の関数形式を使用することが適切でない理由についての洞察を提供する別のリンクForEachです。

于 2010-01-07T20:42:07.477 に答える
3

ラムダ式でパラメーターに型を指定できますが、クエリですでにfとbを使用しているため、別の名前を使用する必要があります。

(Foo f1、Bar b1)=>..。

編集

return
(
    from 
        f in foos 
    join
        b in bars 
        on f.BarId equals b.Id 
    select 
        new {f, b}
).select(foobar => {foobar.f.BarId = foobar.b.Id; return foobar.f});
于 2010-01-07T20:00:58.760 に答える
1

select(f2、b2)=> {f2.MissingProp = b2.MissingProp; f2を返す}

于 2010-01-07T20:04:57.413 に答える
1

これをLambda構文で書き直してください。

var vf2 = foos.Join(bars, f => f.id, b => b.id, (foo, bar) => { foo.MissingProp = bar.MissingProp; return foo; });

この構文の説明が必要な場合は、私に知らせてください。

于 2010-01-07T20:06:26.383 に答える
1

コンパイラがラムダに渡す正しい型を推測できない場合は、もちろん自分で型を指定できます。

これは正常に機能するはずです。

select
    (Foo f2, b) => { f2.MissingProp = b.MissingProp; return f2; }

すでにお気づきのように、再利用することはできず、fその意味が維持されることを期待できることに注意してください。これは、新しいパラメータを持つ新しいメソッドシグネチャであるため、個別の名前を使用する必要があります。

そうすると、コンパイラは最初の引数がどのタイプであるかをそれ自体で理解できないことに気付きますが、上記のように指定することはできます。

于 2010-01-07T21:00:13.013 に答える