C#Linqステートメントまたはサブセットを合計するためのforeach()
質問
これらの解決策のどれが好ましいですか?
リストの場合:
List<ExampleInfo> exampleList = new List<ExampleInfo>();
public class ExampleInfo
{
internal ExampleInfo()
{ }
/* Business Properties */
public int Id { get; set; }
public string Type { get; set; }
public decimal Total { get; set; }
}
「合計」値に基づいて小計を取得したい。
オプション1:
var subtotal1 = exampleList.Where(x => x.Type == "Subtype1").Sum(x => x.Total);
var subtotal2 = exampleList.Where(x => x.Type == "Subtype2").Sum(x => x.Total);
オプション2:
decimal subtotal1 = 0m;
decimal subtotal2 = 0m;
foreach (ExampleInfo example in exampleList)
{
switch (example.Type)
{
case "Subtype1":
subtotal1 += example.Total;
break;
case "Subtype2":
subtotal2 += example.Total;
break;
default:
break;
}
}
ほとんどの場合、リストは<!> lt; 10アイテムです。
編集:クリスは、私が言及しなかった非常に良い点を挙げました。プログラムはすでに.NET Framework 3.5 SP1を使用しているため、互換性はここでは重要な考慮事項ではありません。
解決
これらの例は両方ともコードが重複しており、どちらもType
の変更の準備ができていません-3つの値があった場合はどうなりますか? 30だったらどうなりますか?
linqを使用してグループ化し、合計を取得できます。
var totals = from p in exampleList
group p by p.Type into g
select new { Type = g.Key, Total = g.Sum(p => p.Total ) };
つまり、totals
はプロパティTotal
および<=>
他のヒント
リストサイズに関係なく、.NET 3.5をターゲットにしている場合は、読みやすくするために、LINQを使用します。
私はあなたが言っていることを書くことの大ファンであり、それがどのように行われるかではなく、LINQはそのような場合にこれを非常に簡単にします。
計算を単一のLINQステートメントにプルし、タイプごとにグループ化することもできます。そうすれば、LINQのループは2つではなく、2番目の例のように1つだけになります。
var subtotals = from x in exampleList
group x by x.Type into g
select new { Type = x.Key, SubTotal = g.Sum(x => x.Total) };
(コードが正常に機能するかどうかは完全にはわかりませんが、 101 LINQサンプル。ただし、構文は問題ないはずです。)
オプション3
var groupings = exampleList
.GroupBy(x => x.Type, x => x.Total)
.Select(x => new { Type = x.Key, SubTotal = x.Sum() } );
次のようなクラスのリストがあります:
class <Anonymous>
{
public string Type { get; }
public decimal SubTotal { get; }
}
列挙して適切な値に割り当てますが、このような小さなセットでは過剰な場合があります。
このような小さなリストのパフォーマンスに大きな違いはないと思います。
オプション1はリストを2回繰り返しますが、オプション2はリストを1回だけ繰り返します。これは、小さいリストよりも大きいリストの場合に注意する必要がある場合があります。
オプション1は読みやすいですが、リストを2回繰り返すコメントを必ず作成します。
オプション2の明らかな利点は、コードが.NET Framework 2.0で機能することです。 LINQを使用すると、アプリケーションに.NET Framework 3.5が必要になります。
option1の場合、内部的にforeachループはC#ランタイムenvによって2回実行されます。したがって、処理タイプはより多くなります。しかし、<!> lt; 10個のアイテムの場合、違いはほとんどなく、オプション1はより読みやすいようです。 <!> ltにはオプション1を使用します。 10アイテム。