6 Stimmen

C# Linq-Anweisungen oder ein foreach() für die Zusammenfassung von Teilmengen?

Welche dieser Lösungen ist vorzuziehen?

Für eine Liste:

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

Ich möchte Zwischensummen auf der Grundlage des Werts "Gesamt" erhalten.

Option 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);

Option 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;

    }
}

Die Liste wird in den meisten Fällen weniger als 10 Punkte umfassen.

Bearbeiten: Chris hat einen sehr guten Punkt angesprochen, den ich nicht erwähnt habe. Das Programm verwendet bereits .NET Framework 3.5 SP1, so dass die Kompatibilität hier keine wichtige Rolle spielt.

5voto

Joey Punkte 329386

Unabhängig von der Größe der Liste, wenn Sie .NET 3.5 anstreben, würde ich mit LINQ gehen, wenn auch nur für die Lesbarkeit.

Ich bin ein großer Fan davon, zu schreiben, was man meint, und nicht, wie es gemacht wird, und LINQ macht dies in solchen Fällen sehr einfach.

Sie können die Berechnungen wahrscheinlich sogar in einer einzigen LINQ-Anweisung zusammenfassen und nach Typ gruppieren. Auf diese Weise haben Sie nicht zwei Schleifen für LINQ, sondern nur eine wie im zweiten Beispiel:

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

(Ich bin mir nicht ganz sicher, ob der Code so funktioniert, es ist nur eine schnelle Adaption von einem der 101 LINQ-Beispiele . Die Syntax sollte aber in Ordnung sein.)

4voto

Talljoe Punkte 14181

Option 3

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

Sie erhalten eine Liste von Klassen wie folgt:

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

Aufzählen und dem entsprechenden Wert zuordnen, auch wenn das bei einer so kleinen Menge vielleicht zu viel ist.

4voto

Kobi Punkte 129985

Beide Beispiele enthalten doppelten Code, und beide sind nicht bereit für eine Änderung am Type - Was wäre, wenn es drei Werte hätte? Was wäre, wenn er 30 Werte hätte?
Sie können linq verwenden, um danach zu gruppieren und die Summe zu erhalten:

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

Also totals ist eine Sammlung von Objekten mit den Eigenschaften Type y Total

2voto

Chris Thompson Punkte 15343

Ich glaube nicht, dass es bei so kleinen Listen einen großen Leistungsunterschied geben würde.

Bei Option 1 wird die Liste zweimal durchlaufen, während bei Option 2 die Liste nur einmal durchlaufen wird. Dies kann bei größeren Listen wichtiger sein als bei kleinen.

Option 1 ist besser lesbar, aber ich würde auf jeden Fall darauf achten, dass die Liste zweimal durchlaufen wird.

Der offensichtliche Vorteil von Option 2 ist, dass der Code in .NET Framework 2.0 funktioniert. Die Verwendung von LINQ bedeutet, dass Ihre Anwendung .NET Framework 3.5 benötigt.

1voto

SO User Punkte 22342

Bei Option 1 wird die foreach-Schleife intern zweimal von der C#-Laufzeitumgebung ausgeführt. Daher wird der Verarbeitungstyp mehr sein. Aber für <10 Elemente, macht es kaum einen Unterschied, und Option 1 scheint mehr lesbar. Für < 10 Elemente würde ich mich für Option 1 entscheiden.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X