3

Is there a one line LINQ statement that would replace the foreach loop in the code below?

public static ReplaceItemsOnOrder(Order order, List<OrderItem> replacements)
{
    order.Items.Clear();
    foreach (var item in replacements)
    {
        order.Items.Add(item);
    }
}

EDIT:

Here is a simplified definition for the Order class:

public class Order
{
    private Collection<OrderItem> _items = new Collection<OrderItem>();
    public Collection<OrderItem> Items
    {
        get { return _items; }
    }
}
Ɖiamond ǤeezeƦ
  • 3,223
  • 3
  • 28
  • 40

4 Answers4

3

It's not LINQ but there's AddRange

order.Items.AddRange(replacements);

But you haven't said what Items is, so unless it's a List that method won't be available.

ChrisF
  • 134,786
  • 31
  • 255
  • 325
  • If it's not a List but implements IEnumerable, he just has to call .ToList() on it, and AddRange will be available. – Louis Kottmann Jan 17 '12 at 13:01
  • @Baboon: `System.Linq.Enumerable.ToList(this IEnumerable)` creates a _new_ list with all item references copied, so for this to work OP has to store the list anywhere. – Nuffin Jan 17 '12 at 13:05
  • @Tobias order.Items.ToList().AddRange(replacements) doesn't require him to store the list anywhere, AddRange is void. – Louis Kottmann Jan 17 '12 at 13:09
  • @Baboon: That's true, but the `AddRange` method alters the newly created list, not the enumeration the list was created from. – Nuffin Jan 17 '12 at 13:20
3

You could write the following:

order.Items.Clear();
replacements.ForEach(order.Items.Add);

Alternatively if there's an addRange method (available on List<T>):

order.Items.Clear();
order.Items.AddRange(replacements);
Rich O'Kelly
  • 41,274
  • 9
  • 83
  • 114
2

Is order.Items a List? You could have:

public static ReplaceItemsOnOrder(Order order, List<OrderItem> replacements)
{
    order.Items = new List<OrderItem>(replacements);
}

This makes sense because, in your example code, it seems you're replacing the items in order.Items. List<T> has a constructor which accepts an IEnumerable<T> argument, whose contents will be copied to the list being constructed.

It's also safer in the sense that if an error occurrs at construction time (including the copy operation), it won't result in a half-full new list.

Humberto
  • 7,117
  • 4
  • 31
  • 46
2

No, Linq is about selecting, not modifying.

You could write your own extension method to add this feature though.

vc 74
  • 37,131
  • 7
  • 73
  • 89