我有一个有两个属性的类,比如说
public class Book {
public string TitleSource { get; set; }
public string TitleTarget { get; set; }
}
我有一个IList<Book>
TitleTarget
为空,对于列表中的每个项目,我需要将TitleSource
属性复制到TitleTarget
属性。我可以通过一个循环来做到这一点,当然,但似乎有一个LINQ或很好的声明方式来做到这一点。有吗?
答案 0 :(得分:4)
Linq被设计为一种消费方式。如果你看一下关于为什么没有IEnumerable.ForEach(...)扩展的网络讨论,你会发现Linq设计者有目的地避免了Linq to Object场景,其中方法被设计为改变对象值。
也就是说,您可以通过“选择”值而不使用结果来作弊。但是,这会产生被扔掉的物品。因此,foreach循环效率更高。
为真正想要除了foreach之外的其他人
进行编辑另一个不会产生新列表的“作弊”将是使用一种方法来完成它自己的工作,如Aggregate,All或Any。
// Return true so All will go through the whole list.
books.All(book => { book.TitleTarget = book.TitleSource; return true; });
答案 1 :(得分:1)
这不是LINQ,但是有:
books.Where(book => book.TitleTarget == null).ToList()
.ForEach(book => book.TitleTarget = book.TitleSource);
主要观点是ToList
方法调用:没有ForEach
扩展方法(我不认为?)但直接在List<T>
上有一个方法。编写自己的ForEach
扩展方法也不难。
至于这是否比简单的foreach
循环好,我不太确定。我个人会选择foreach
循环,因为它使意图(你想要修改集合)更清晰。
答案 2 :(得分:1)
@John Fisher是正确的,没有IEnumerable.ForEach
。
List<T>
上有一个ForEach。所以你可以做到以下几点:
List<Book> books = GetBooks();
books.ForEach(b => b.TitleTarget = b.TitleSource);
如果你想要一个IEnumerable.ForEach,那么很容易创建一个:
public static class LinqExtensions
{
public static void ForEach<TSource>(this IEnumerable<TSource> source, Action<TSource> action)
{
foreach (var item in source)
{
action(item);
}
}
}
然后,您可以使用以下代码段在整个集合中执行操作:
IList<Book> books = GetBooks();
books.ForEach(b => b.TitleTarget = b.TitleSource);
答案 3 :(得分:1)
如果您可以使用.NET 4.0,并且您使用的是线程安全的集合,那么您可以使用新的并行ForEach构造:
using System.Threading.Tasks;
...
Parallel.ForEach(
books.Where(book => book.TitleTarget == null),
book => book.TitleTarget = book.TitleSource);
这将排队要在线程池上运行的任务 - 一个任务将执行集合中每本书的赋值委托。
对于大型数据集,这可能会提高性能,但是考虑到管理线程同步的开销,对于较小的集合实际上可能会更慢。
答案 4 :(得分:0)
books.Select(b => b.TitleTarget = b.TitleSource);
这不会创建任何“新项目”,只是您不会枚举的查询。这对我来说似乎没什么大不了的。