有没有使用LINQ实现以下操作的方法?
foreach (var c in collection)
{
c.PropertyToSet = value;
}
为了澄清,我想遍历集合中的每个对象,然后更新每个对象上的某个属性。
我的使用场景是在博客文章上有许多评论,并且我想遍历每个评论并将博客文章的日期时间设置为+10小时。我可以在SQL中完成,但我想将其保留在业务层。
有没有使用LINQ实现以下操作的方法?
foreach (var c in collection)
{
c.PropertyToSet = value;
}
为了澄清,我想遍历集合中的每个对象,然后更新每个对象上的某个属性。
我的使用场景是在博客文章上有许多评论,并且我想遍历每个评论并将博客文章的日期时间设置为+10小时。我可以在SQL中完成,但我想将其保留在业务层。
虽然您可以使用 ForEach
扩展方法,但如果您想仅使用框架,则可以执行以下操作
collection.Select(c => {c.PropertyToSet = value; return c;}).ToList();
< p > ToList
是必须的,因为由于“惰性求值”,需要立即计算选择结果。 < /p >ObservableCollection
的话,那么在原地更改项目而不是创建新列表可以很有用。 - Cameron MacFarlandcollection.ToList().ForEach(c => c.PropertyToSet = value);
collection.ToList().ForEach(c => { c.Property1ToSet = value1; c.Property2ToSet = value2; });
。 - Ε Г И І И Оc
是引用类型,则以这种方式设置PropertyToSet
的行为符合预期。请参见https://pastebin.com/rtG2i1KX。 - BrianCollection.All(c => { c.needsChange = value; return true; });
All()
扩展方法的本意,会导致其他人阅读代码时出现潜在的混淆。 - Tom BaxterList<>
这样的集合,那么ForEach()
方法是一种更不神秘的实现方式。例如:ForEach(c => { c.needsChange = value; })
- Dan Is Fiddling By Firelightpublic static IEnumerable<T> ForEach<T>(
this IEnumerable<T> source,
Action<T> act)
{
foreach (T element in source) act(element);
return source;
}
foreach
循环(无论出于何种原因),那么这是唯一有用的方法。 - Tim Schmelter扩展方法:
foos.ForEach((Foo foo)=>{ statement involving foo; });` - Simon Elmsvoid
方法。问题在于,这实际上是一个“实现集合”的方法,假装成一个“添加更多惰性处理”的方法。这是一个假装成惰性的非惰性过程。 - Dave Cousineau使用:
ListOfStuff.Where(w => w.Thing == value).ToList().ForEach(f => f.OtherThing = vauleForNewOtherThing);
我不确定这是否过度使用了LINQ,但当想要针对特定条件更新列表中的特定项时,这对我很有帮助。
虽然你明确要求了一个LINQ解决方案,而且这个问题很旧了,但我发布了一个非LINQ解决方案。这是因为LINQ (= language integrated query) 用于集合查询。所有LINQ方法都不修改基础集合,它们只返回一个新的(或更精确地说是新集合的迭代器)。因此,无论你使用什么方法,例如Select
,都不会影响基础集合,你只会得到一个新集合。
当然,你也可以使用ForEach
(顺便说一下,这不是LINQ,而是对List<T>
的扩展)。但是这实际上仍然使用了foreach
,只是用了lambda表达式。除此之外,每个LINQ方法在内部迭代集合,例如使用foreach
或for
,但它只是从客户端隐藏了这一点。我认为这并不更可读或易于维护(考虑在调试包含lambda表达式的方法时编辑代码)。
话虽如此,你不应该使用LINQ来修改你的集合中的项目。更好的方式是你已经在问题中提供的解决方案。通过经典循环,你可以轻松地迭代你的集合并更新它的项目。事实上,那些依赖于List.ForEach
的解决方案并没有什么不同,但从我的角度来看更难以阅读。
因此,在您想要更新集合元素的情况下,不应该使用LINQ。
for
循环。我认为它是一种语法糖,用于创建更简洁的方式来完成简单的任务,而不是替代标准编码。 - ForeverZer0没有内置的扩展方法来完成这个任务。虽然定义一个扩展方法相当简单。在本文底部有一个我定义的名为Iterate的方法。可以像下面这样使用:
collection.Iterate(c => { c.PropertyToSet = value;} );
迭代源代码
public static void Iterate<T>(this IEnumerable<T> enumerable, Action<T> callback)
{
if (enumerable == null)
{
throw new ArgumentNullException("enumerable");
}
IterateHelper(enumerable, (x, i) => callback(x));
}
public static void Iterate<T>(this IEnumerable<T> enumerable, Action<T,int> callback)
{
if (enumerable == null)
{
throw new ArgumentNullException("enumerable");
}
IterateHelper(enumerable, callback);
}
private static void IterateHelper<T>(this IEnumerable<T> enumerable, Action<T,int> callback)
{
int count = 0;
foreach (var cur in enumerable)
{
callback(cur, count);
count++;
}
}
public static class UpdateExtensions {
public delegate void Func<TArg0>(TArg0 element);
/// <summary>
/// Executes an Update statement block on all elements in an IEnumerable<T> sequence.
/// </summary>
/// <typeparam name="TSource">The source element type.</typeparam>
/// <param name="source">The source sequence.</param>
/// <param name="update">The update statement to execute for each element.</param>
/// <returns>The numer of records affected.</returns>
public static int Update<TSource>(this IEnumerable<TSource> source, Func<TSource> update)
{
if (source == null) throw new ArgumentNullException("source");
if (update == null) throw new ArgumentNullException("update");
if (typeof(TSource).IsValueType)
throw new NotSupportedException("value type elements are not supported by update.");
int count = 0;
foreach (TSource element in source)
{
update(element);
count++;
}
return count;
}
}
int count = drawingObjects
.Where(d => d.IsSelected && d.Color == Colors.Blue)
.Update(e => { e.Color = Color.Red; e.Selected = false; } );
Action<TSource>
而不是创建额外的委托。尽管在撰写本文时可能还没有这个选项。 - Frank Jwhere T: struct
,在编译时捕获它。 - vgru有些人认为这是一条评论,但对我而言,它是一个答案,因为做错事情的正确方法就是不去做。因此,这个问题的答案就在问题本身。
不要使用LINQ来修改数据。使用循环。