есть ли лучший способ сделать это?
Совпадающий массив, подобный этому, является анти-шаблоном и признаком того, что вы действительно должны создать класс со свойствами для цены, товара и корзины. Тогда у вас может быть один массив, который вы можете просмотреть только один раз.
Но вы все равно можете делать то, что вам нужно, даже с этим анти-паттерном:
var items = cart.Zip(goods, (c,g) => new {Cart = c, Good = g}).Zip(price, (a, p) => new {Cart = a.Cart, Good = a.Good, Price = p});
var ticked = items.Where(i => i.Cart);
var message = string.Join(",", ticked.Select(t => t.Good));
var sum = ticked.Select(t => t.Price).Sum();
MessageBox.Show($"{message}\nTotal: {sum}");
Это также будет работать и может означать меньшее использование памяти:
var ticked = cart.Select((value,index) => new {Cart = value, Price = price[index], Good = goods[index]})
.Where(i => i.Cart);
var message = string.Join(",", ticked.Select(s => s.Good));
var sum = ticked.Select(s => s.Price).Sum();
MessageBox.Show($"{message}\nTotal: {sum}");
Вы также можете использовать индексы:
int sum = 0;
var message = new StringBuilder();
var delimiter = "";
for(int i = 0; i<cart.Length; i++)
{
if (cart[i])
{
sum += price[i];
message.Append(delimiter).Append(goods[i]);
delimiter = ",";
}
}
MessageBox.Show($"{message}\nTotal: {sum}");
И в этом случае опция индекса, вероятно, быстрее и не сложнее для понимания опции linq (хотя очень часто наоборот), даже если это больше кода.