我想在.First()
内使用匿名函数,但是我应该使用另一个扩展名,我应该为此使用,因为.First()
期望predicate
。
基本上,想要一次更新多个属性,与在.ForEach()
中使用匿名函数非常相似。
有人为我提供了知识掉落吗?
ex:
//what i could do, but don't want to do
var person = people.First();
person.FirstName = "john";
person.LastName = "doe";
//where I am currently at, but can only access 1x property at a time
people.First().FirstName = "john";
//what I would like to do
people.First(x => {
x.FirstName = "john";
x.LastName = "doe";
});
//pattern im copying
people.ForEach(fe => {
Console.WriteLine(fe.FirstName);
Console.WriteLine(fe.LastName);
});
更新我坚信原始方法是最好的。感谢所有人的帮助和指导。
collection.First(x => [function]);
与写作相同
collection.Where(x => [function]).First();
linq是一种查询语言,因此用于过滤,汇总和投影,而不是突变。正如您发现的那样,第一个()除了对过滤的谓词外,没有一个过载。
您在示例的第一部分中所做的是正确的用法,没有包装盒的LINQ语句可以按照您想写的方式来做您的要求(并且同样,按照您的第一次使用方式做事没有错)。
这实际上是最丑陋的方法,但实际上是可能的::d
people.First(x =>
{
x.FirstName = "john";
x.LastName = "doe";
return true;
});
First()
需要一个谓词来过滤列表,因此必须将其评估为bool
。只要您返回 true
,它将起作用。
返回false
抛出InvalidOperationException
,带有消息:Sequence contains no matching element
。
评论是正确的,您应该使用第一种方法。但是,如果您想花哨的东西,可以使用
people.Take(1).ForEach(x =>
{
x.FirstName = "john";
x.LastName = "doe";
});
我已经在评论中提到了使用linq-设计用于 Querying 项目,而不是用于操纵他们 - 以执行您的操作'描述的完全是错误的,不建议。
当然,您可以写自己的扩展名方法:
public static class MyWierdExtensions
{
public static void ExecuteOnFirst<T>(this IEnumerable<T> source, Func<T, bool> predicate, Action<T> exec)
{
var element = source.First(predicate);
exec(element);
}
}
现在您应该能够称呼它:
myEnumerable.ExecuteOnFirst(x => x.Id == 1, x => x.MyProperty = 3);
甚至 - 根据您的意愿:
people.ExecuteOnFirst(x => x.Id == 1, x =>
{
x.FirstName = "john";
x.LastName = "doe";
}
但是,我怀疑您通过编写这种代码会得到任何改进。我强烈建议您使用您当前的方法:使用First(predicate)
获取该物品,然后通过访问属性设置器来操纵它。