LINQ суммирование элементов для возврата объекта с результатами (несколько столбцов)

Я знаю, что могу сделать это с помощью foreach, но задавался вопросом, есть ли в LINQ чистый и "более сексуальный" способ.

public class item
{
    public int total { get; set; }
    public int net { get; set; }
}


class Program
{
    static void Main(string[] args)
    {
        List<item> items = new List<item>()
                               {
                                   new item() { total = 123, net = 423},
                                   new item() { total = 432, net = 54},
                                   new item() { total = 33, net = 57654},
                                   new item() { total = 33, net = 423},
                                   new item() { total = 3344, net = 423},
                                   new item() { total = 123, net = 423},
                                   new item() { total = 123, net = 98},
                                   new item() { total = 123, net = 867},
                                   new item() { total = 123, net = 876},
                                   new item() { total = 123, net = 423},
                                   new item() { total = 123, net = 543},
                                   new item() { total = 543, net = 345},
                               };

        item i = new item();
        foreach (var item in items)
        {
            i.net += item.net;
            i.total += item.total;
        }
    }
}

Что я хотел бы сделать, так как данный список объектов суммирует каждый из столбцов/полей и возвращает один единственный объект с суммой каждого значения.

Я пробовал:

var result = (from e in items
                     select new
                                {
                                    NET_GRAND = e.net,
                                    TOTAL_GRAND = e.total
                                }).ToList();

И варианты ниже, но без везения:

 var result = (from t in items
                     group t by new {t.net, t.total}
                     into grp
                     select new
                                {
                                    NET_GRAND = grp.Sum(t => t.net),
                                    TOTAL_GRAND = grp.Sum(t => t.total)
                                }).GroupBy(x => new { x.NET_GRAND, x.TOTAL_GRAND }).ToList();

ИЗМЕНИТЬ

должен был указать, что здесь важна эффективность, а также сексуальность.

Ответ 1

Если вам не нужно дважды повторять список,

var i = new item
    { 
        net = items.Sum(it => it.net), 
        total = items.Sum(it => it.total) 
    };

Если вы позаботились о повторении списка дважды (как вы могли бы, если бы вы делали это для IEnumerable неизвестного происхождения),

var i = items.Aggregate(new item(), 
    (accumulator, it) => 
        new item 
        {
            net = accumulator.net + it.net, 
            total = accumulator.total + it.total 
        } 
);

Ответ 2

Похоже, вы действительно хотите:

var result = new {
    NetGrand = items.Sum(t => t.net),
    TotalGrand = items.Sum(t => t.total)
};

С другой стороны, я бы, вероятно, просто разделил их на две разные локальные переменные:

var netGrand = items.Sum(t => t.net);
var totalGrand = items.Sum(t => t.total);

Конечно, это повторяется по списку дважды, но в большинстве случаев я ожидаю, что это не будет заметно.

Ответ 3

item totals = new item 
              { 
                 net = items.Sum(i => i.net),
                 total = items.Sum(i => i.total)  
              };

Но имейте в виду, что этот запрос будет перечислять список два раза, поэтому для большого списка это будет не так эффективно, как старый хороший одиночный цикл foreach.

Ответ 4

var item = new item();
item.net = items .Sum(x=>x.net);
item.total = items.Sum(x=>x.total);

Ответ 5

Используйте цикл foreach. Вы заявляете, что вас беспокоит эффективность, и даже если вы не были там, нет причин писать его с помощью Linq только для использования Linq.

Одна из вещей, которые мы обнаруживаем, когда мы получаем больше опыта работы с программами, состоит в том, что только потому, что что-то делается "по-старому", не делает это плохо. И переход на новый метод wiz-bang не делает его лучше. Фактически, если у вас есть код, работающий по-старому, "обновление" является причиной для инъекций дефектов, во многих случаях нет преимуществ.

В лучшем случае этот метод Linq займет 2X для вычисления.

var i = new item
    { 
        net = items.Sum(it => it.net), 
        total = items.Sum(it => it.total) 
    };

Не уверен в сводном методе, но, очевидно, это займет больше времени.