11

ForEachのラムダ式に条件演算子を含めることは許可されていませんか?

List<string> items = new List<string>{"Item 1", "Item 2", "Item I Care About"};

string whatICareAbout = "";

// doesn't compile :(
items.ForEach(item => item.Contains("I Care About") ? 
whatICareAbout += item + "," : whatICareAbout += "");

コンパイルエラー->「ステートメントとして使用できるのは、代入、呼び出し、インクリメント、デクリメント、および新しいオブジェクト式のみです」

どちらも機能しない場合に通常を使用しようとしています:

// :(
items.ForEach(item => if (item.Contains("I Care About")) {whatICareAbout += item + ", ";}

不可能ですか?

4

4 に答える 4

33

単一の式のみを許可する短い形式のラムダ式を使用しています。
複数のステートメントを許可する長い形式にする必要があります。

例えば:

items.ForEach(item => {
    if (item.Contains("I Care About")) 
        whatICareAbout += item + ", ";
});
于 2009-11-29T21:44:05.127 に答える
6

何を達成しようとしていますか?特定の値を含むコンマ区切りのアイテムの文字列を作成しようとしていますか?linqでは、次を使用してこれを実現します。

 List<string> items = new List<string> { "Item 1", "Item 2", "Item I Care About", "Item I Care About", "Item I Care About" }; 
 string whatICareAbout = items.Where(x => x.Contains("I Care About"))
                              .Aggregate( (y, z) => y + ", " + z);

これからの出力は、「アイテムIケアアバウト、アイテムIケアアバウト、アイテムIケアアバウト」です。

注:集計は、末尾に「、」がないことを確認するための優れた方法です。

于 2009-11-29T21:52:35.453 に答える
4

問題はその表現でした

item.Contains("I Care About") ? whatICareAbout += item + "," : whatICareAbout += ""

ステートメントではありません。タイプが。の値を返すだけstringです。

それを機能させるためのトリックがあります(楽しみのためだけに):

    items.ForEach(item => (item.Contains("I Care About") ?
    whatICareAbout += item + "," : whatICareAbout += "").GetType());

.GetType()最初の式からステートメントを作成するためのメソッドの呼び出しを追加するだけで、コンパイルされました。

于 2009-11-29T22:22:10.313 に答える
1

かっこを試してください:

items.ForEach(item => item.Contains("I Care About") ? (whatICareAbout += item + ",") : (whatICareAbout += "") );

+ =は?よりも優先順位が高いため、エラーが発生する可能性があります。括弧を使用すると、エラーがなくなる場合があります。ただし、これを100%確信しているわけではありません...ラムダ式には、代入ステートメントの使用を妨げる追加の制限がある場合があります。

アップデート:

複数の+=ステートメントの代わりに、次のように、割り当ての右側に条件を配置する方がはるかにクリーンです。

List<string> items = new List<string> { "one", "two", "three" };
string whatICareAbout = "";
items.ForEach(item => whatICareAbout +=  item.Contains("I Care About") ? (item + ",") : ""); 

更新2:

ただし、Aggregate()はまさにこのシナリオ向けに設計されているため、Aggregate()を使用することをお勧めします。これが1つのサンプルです:

string whatICareAbout = items.Aggregate("", (total, item) => item.Contains("I Care About") ? (total + item + ",") : total);

しかし、上記の@Matt Breckonの回答(これを投稿しようとしていたときに見たもの)は、端末 "、"の削除を扱っているため、私の例よりもさらに優れていると思います。彼の答えを見てください...:-)

于 2009-11-29T21:45:03.597 に答える