2009-06-22 20 views
6

Bu çözümlerden hangisi tercih edilir? Bir Liste için C# Linq ifadeleri veya toplam alt kümeler için 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; } 
} 

Ben 'Toplam' değerini kapalı tabanlı alt toplamları almak istiyoruz.

Seçenek 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); 

Seçenek 2: Liste çoğu durumda < 10 ürün olacaktır

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; 

    } 
} 

.

Düzelt: Chris çok iyi bir noktaya değindim, bahsetmedim. Program zaten .NET Framework 3.5 SP1 kullanıyor, dolayısıyla uyumluluk önemli bir konu değil.

cevap

4

Bu örneklerin her ikisi de çoğaltılmış kod içeriyor ve her ikisi de Type üzerinde bir değişiklik yapmaya hazır değil - üç değeri varsa ne olacak? Ya 30 yaşındaysa?
Bunu tarafından gruba linq kullanmak ve toplam alabilir:

var totals = from p in exampleList 
      group p by p.Type into g 
      select new { Type = g.Key, Total = g.Sum(p => p.Total) }; 

Yani totals hiç döngü yürütmüyor özellikleri Type ve Total

+0

Tam olarak ne yazıyordum aynı anda yazıyordum :) –

+0

Sadece işlevsel eşdeğer yazdım –

2

Bu küçük listelerde çok fazla performans farkı olacağını düşünmüyorum.

Seçenek 1, listede iki kez yinelenirken Seçenek 2, yalnızca listeden bir kez yinelenir. Küçük listelerden daha büyük listeler için not etmek daha önemli olabilir.

Seçenek 1 daha okunabilir, ancak listeyi iki kez yinelediğine dair bir yorum yaptığınızdan kesinlikle emin olabilirsiniz.

Seçenek 2'deki açık avantaj, kodun .NET Framework 2.0'da çalışmasıdır. LINQ kullanımı, uygulamanızın .NET Framework 3.5 gerektirdiği anlamına gelir.

5

Liste boyutu ne olursa olsun, .NET 3.5'ü hedefliyorsanız, yalnızca okunabilirlik için LINQ ile giderdim.

Ne demek istediğini yazmanın harika bir hayranıyım, nasıl yapıldığını değil ve LINQ bu gibi durumlarda bunu çok kolaylaştırıyor.

Muhtemelen hesaplamaları, Tür'e göre gruplandırarak tek bir LINQ ifadesine bile alabilirsiniz. .

var subtotals = from x in exampleList 
       group x by x.Type into g 
       select new { Type = x.Key, SubTotal = g.Sum(x => x.Total) }; 

(kod kendisine şekilde çalışıp çalışmadığını tam olarak emin değiliz, bu 101 LINQ Samples birinden sadece hızlı adaptasyonu var dizimi: Bu yolla iki LINQ için döngüler ama ikinci örnekte olduğu gibi sadece bir tane olmaz olsa da, iyi olmalıdır.)

1

Seçenek1 için, içten döngü döngüsü C# çalışma zamanı env tarafından iki kez yürütülür. Dolayısıyla işlem tipi daha fazla olacaktır. Fakat < 10 maddede, herhangi bir fark yaratmıyor ve 1 seçeneği daha okunabilir görünüyor. < 10 ürün için seçenek 1 ile giderdim.

class <Anonymous> 
{ 
    public string Type { get; }  
    public decimal SubTotal { get; } 
} 

Numaralandır ve böyle küçük bir set için boğucu olabilir ancak uygun değere atama:

+0

C# derleyicisi ile nesnelerin topluluğudur. Uygulama zamanında yapıldı. –

+0

Teşekkürler Jon. 'Derleyici', 'çalışma zamanı env' olarak değiştirildi. –

4

Seçenek 3

var groupings = exampleList 
    .GroupBy(x => x.Type, x => x.Total) 
    .Select(x => new { Type = x.Key, SubTotal = x.Sum() }); 

Öyle gibi sınıflarının listesini gerekecek.