使用LINQ是否有更简洁的方式向集合属性添加项?

3
有没有一行LINQ语句可以取代下面代码中的foreach循环?
public static ReplaceItemsOnOrder(Order order, List<OrderItem> replacements)
{
    order.Items.Clear();
    foreach (var item in replacements)
    {
        order.Items.Add(item);
    }
}

编辑:

这里是Order类的简化定义:

public class Order
{
    private Collection<OrderItem> _items = new Collection<OrderItem>();
    public Collection<OrderItem> Items
    {
        get { return _items; }
    }
}

订单中的Items属性是否比ICollection<OrderItem>更为派生? - Rich O'Kelly
请查看https://dev59.com/GHVC5IYBdhLWcg3wtzyt。 - Slugart
我已更新问题以显示Order.Items类型,它是Collection<OrderItem>。 - Ɖiamond ǤeezeƦ
4个回答

3

这不是LINQ,但有AddRange方法。

order.Items.AddRange(replacements);

但是你没有说明Items是什么,所以除非它是一个List,否则该方法将不可用。

如果它不是List但实现了IEnumerable,他只需要在其上调用.ToList(),AddRange将可用。 - Louis Kottmann
@Baboon: System.Linq.Enumerable.ToList<T>(this IEnumerable<T>) 会创建一个新的列表,并将所有项的引用复制到其中,因此为了使其正常工作,OP必须在任何地方存储该列表。 - Nuffin
@Tobias order.Items.ToList().AddRange(replacements) 不需要他在任何地方存储列表, AddRange 是 void。 - Louis Kottmann
@Baboon:没错,但是 AddRange 方法会修改新创建的列表,而不是创建该列表的枚举。 - Nuffin

3
您可以编写以下内容:
order.Items.Clear();
replacements.ForEach(order.Items.Add);

如果List<T>上有可用的addRange方法,则可以选择以下方式:

order.Items.Clear();
order.Items.AddRange(replacements);

这段代码也可以写成:replacements.ForEach(order.Items.Add); - Klaus Byskov Pedersen
1
@KlausByskovHoffmann 非常正确,避免使用不必要的匿名方法。已更新。 - Rich O'Kelly

2
不,Linq是关于选择而不是修改的。 但你可以编写自己的扩展方法来添加此功能。

2

order.Items 是一个列表吗?可能会有:

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

这是有道理的,因为在你的示例代码中,似乎你正在替换order.Items中的项目。 List<T>有一个构造函数,它接受一个IEnumerable<T>参数,其内容将被复制到正在构造的列表中。
从安全角度来看,如果在构建时(包括复制操作)发生错误,它也更加安全,不会导致新列表半满的情况。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接