在 C#/LINQ 中用匿名方法替换常规方法
我有一个如下所示的 LINQ 查询:
public IEnumerable<Foo> SelectFooBars()
{
return
from
f in foos
join
b in bars
on f.BarId equals b.Id
select
AddMissingProp(f, b.MissingProp);
}
public void AddMissingProp(Foo foo, string missingProp) // substitute this with inline lambda
{
foo.MissingProp = missingProp;
return foo;
}
我想摆脱 AddMissingProp
并在我的 select
子句中使用某种形式的 lambda。
我尝试...
...
select
(f, b) => { f.MissingProp = b.MissingProp; return f }
...但出现以下错误:
不能在此作用域中声明名为“f”的局部变量,因为它会给“f”赋予不同的含义,而“f”已在“父或当前”作用域中用于表示其他内容。
如何“lambda 化”我的查询?
更新
这也不起作用:
...
select
() => { f.MissingProp = b.MissingProp; return f }
我收到以下错误:
连接子句中的表达式之一的类型不正确。调用“Join”时类型推断失败。
我根本没有更改 join
子句,所以我很困惑。
I have a LINQ query that looks like this:
public IEnumerable<Foo> SelectFooBars()
{
return
from
f in foos
join
b in bars
on f.BarId equals b.Id
select
AddMissingProp(f, b.MissingProp);
}
public void AddMissingProp(Foo foo, string missingProp) // substitute this with inline lambda
{
foo.MissingProp = missingProp;
return foo;
}
I would like to get rid of AddMissingProp
and use some form of a lambda in my select
clause instead.
I attempted...
...
select
(f, b) => { f.MissingProp = b.MissingProp; return f }
...but I got the following error:
A local variable named 'f' cannot be declared in this scope because it would give a different meaning to 'f', which is already used in a 'parent or current' scope to denote something else.
How can I "lambda-ize" my query?
Update
This also doesn't work:
...
select
() => { f.MissingProp = b.MissingProp; return f }
I get the following error:
The type of one of the expressions in the join clause is incorrect. Type inference failed in the call to 'Join'.
I didn't change the join
clause at all, so I'm perplexed.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我认为 icambron 是对的,恕我直言,更好的可读版本是这样的:
from join select
语句用于查询,它们不应该被滥用来改变序列的内容。编辑:这是另一个链接提供了一些见解,说明为什么使用
ForEach
的函数形式不是一个好主意。I think icambron is right, IMHO the better readable version is this:
The
from join select
statements are for queries, they should not be misused for mutating the contents of a sequence.EDIT: Here is another link providing some insights why using a functional form of
ForEach
is not a good idea.您可以在 lambda 表达式中为参数指定类型,但需要使用不同的名称,因为您已经在查询中使用了 f 和 b。
(Foo f1, Bar b1) => ...
编辑
You can give types to your parameters in a lambda expression but you need to use different names since you're already using f and b in the query.
(Foo f1, Bar b1) => ...
Edit
选择
(f2,b2)=> { f2.MissingProp = b2.MissingProp;返回 f2 }
select
(f2, b2) => { f2.MissingProp = b2.MissingProp; return f2 }
使用 Lambda 语法重写它。
如果您需要此语法的解释,请告诉我。
Rewrite this with Lambda syntax.
If you need explanation of this syntax, let me know.
如果编译器无法推断出传递给 lambda 的正确类型,您当然可以自己指定类型。
这应该可以正常工作:
请注意,正如您已经注意到的,您不能重用
f
并希望它保留其含义。这是一个新的方法签名,具有新的参数,因此您需要为其使用不同的名称。当您这样做时,您会注意到编译器无法自行确定第一个参数应该是什么类型,但您可以指定它,就像上面一样。
If the compiler isn't able to infer the correct type to pass to a lambda, you can of course specify the type yourself.
This should work fine:
Note that as you've already noticed, you cannot reuse
f
and hope that it will retain its meaning. This is a new method signature, with new parameters, so you need to use a distinct name for it.When you do, you notice that the compiler isn't able to figure out by itself what type the first argument should be, but you can specify it, like above.