如何缩短以下代码,可能使用匿名方法或扩展名LINQ
。
由于我必须多次重复此代码,因此我希望尽可能简洁。
var imagesToUnlock = App.ImageListVM.Items.Where(img => img.Category == key);
foreach (var image in imagesToUnlock)
{
image.IsLocked = false;
}
答案 0 :(得分:7)
这里的其他解决方案感觉很脏,因为它们通过使用LINQ来改变集合中的对象。
我会将代码和过滤条件放入扩展方法并调用:
public static IEnumerable<Item> UnlockWhere(this IEnumerable<Item> list, Func<Item, bool> condition) {
foreach (var image in list)
if (condition(image)) {
image.IsLocked = false;
yield return image;
}
}
保持LINQ的不变性问题不变并仍然产生预期的结果。
电话变为:
var unlockedItems = App.ImageListVM.Items.UnlockWhere(img => img.Category == key);
修改强>
重写以完全删除LINQ。相反,这个新方法只迭代一次并返回一个新的变异集合。
答案 1 :(得分:3)
不是最有效的方法,但我相信你可以做到
var imagesToUnlock = App.ImageListVM.Items.Where(img => img.Category == key).ToList().Foreach(f => f.IsLocked = false);
查看List<T>
上的Foreach方法了解详情。
我还要注意(正如一些人在评论中指出的那样),这不被某些人视为最佳做法。你应该看一下Eric Lippert的this article,他会更详细地解释这个问题。
答案 2 :(得分:1)
以下是一种扩展方法
<强>代码强>
public static IEnumerable<T> SetPropertyValues<T>(this IEnumerable<T> items, Action<T> action)
{
foreach (var item in items)
{
action(item);
yield return item;
}
}
<强>用法强>
private class Foo
{
public string Bar { get; set; }
}
[TestMethod]
public void SetPropertyValuesForMiscTests()
{
var foos = new[] { new Foo { Bar = "hi" }, new Foo { Bar = "hello" } };
var newList = foos.SetPropertyValues(f => f.Bar = "bye");
Assert.AreEqual("bye", newList.ElementAt(0).Bar);
Assert.AreEqual("bye", newList.ElementAt(1).Bar);
}
我测试了它并且工作正常。
答案 3 :(得分:-1)
是的,你可以做到这一点。改编自answer。
imagesToUnlock.Select(i => {i.IsLocked = false; return i;}).ToList();
编辑:很多人都说这是不好的做法。我同意dasblinkenlight这里。探索LINQ和C#的极限是我们作为程序员的责任。将对象类型从DTO更改为视图模型或域对象并不是不合理的,我知道它不是最好的,但如果封装和注释,使用select来执行此操作并不是世界末日。但请注意Eric.
解释的最佳做法