在 C# 中连接 Lambda 函数
我想使用 C# 3.5 构建一个谓词来逐段发送到 where 子句。 我创建了一个非常简单的控制台应用程序来说明我得到的解决方案。 这非常有效。 绝对完美。 但我不知道如何或为什么。
public static Func<Tran, bool> GetPredicate()
{
Func<Tran, bool> predicate = null;
predicate += t => t.Response == "00";
predicate += t => t.Amount < 100;
return predicate;
}
当我说“谓词+=”时,这是什么意思? 谓词 -= 似乎不执行任何操作,编译器不喜欢 ^=、&=、*=、/=。
编译器不喜欢 'predicate = predicate + t =>; t.Response....' 也可以。
我偶然发现了什么? 我知道它的作用,但它是如何做到的呢?
如果有人想深入研究更复杂的 lambda,请这样做。
Using C# 3.5 I wanted to build up a predicate to send to a where clause piece by piece. I have created a very simple Console Application to illustrate the solution that I arrived at. This works perfectly. Absolutely perfectly. But I have NO idea how or why.
public static Func<Tran, bool> GetPredicate()
{
Func<Tran, bool> predicate = null;
predicate += t => t.Response == "00";
predicate += t => t.Amount < 100;
return predicate;
}
When I say 'predicate +=', what does that mean? predicate -= appears to do nothing and ^=, &=, *=, /= aren't liked by the compiler.
The compiler doesn't like 'predicate = predicate + t => t.Response....' either.
What have I stumbled on? I know what it does, but how does it do it?
If anyone wants to go delve into more complicated lambda's, please do so.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
“delegate += method”是多播委托的运算符,用于将方法组合到委托中。
另一方面,“委托 -= 方法”是从委托中删除方法的运算符。
它对于行动很有用。
在这种情况下,只有 Method1 和 Method3 将运行,Method2 将不会运行,因为您在调用委托之前删除了该方法。
如果您将多播委托与 Func 一起使用,结果将是最后一个方法。
在本例中,结果将为 3,因为方法“() => 3”是添加到委托的最后一个方法。 无论如何,所有方法都会被调用。
在您的情况下,方法“t => t.Amount < 100”将有效。
如果你想组合谓词,我建议使用这些扩展方法。
用法
编辑:按照 Keith 建议更正扩展方法的名称。
"delegate += method" is operator for multicast delegate to combine method to delegate.
In the other hand "delegate -= method" is operator to remove method from delegate.
It is useful for Action.
In this case, only Method1 and Method3 will run, Method2 will not run because you remove the method before invoke the delegate.
If you use multicast delegate with Func, the result will be last method.
In this case, the result will be 3, since method "() => 3" is the last method added to delegate. Anyway all method will be called.
In your case, method "t => t.Amount < 100" will be effective.
If you want to combine predicate, I suggest these extension methods.
Usage
EDIT: correct the name of extension methods as Keith suggest.
当您在委托类型时使用 += 或 -= 时,只会调用
Delegate.Combine
和Delegate.Remove
。关于多播委托的重要一点是,除了最后执行的委托之外的所有委托的返回值都会被忽略。 它们都会被执行(除非抛出异常),但只使用最后一个返回值。
对于谓词,您可能想做类似的事情:
然后您会这样做:
编辑:这是一个更通用的解决方案,如果有点奇怪的话,它非常有趣......
所以您可以然后实现并且作为:(
我个人更喜欢使用
GetInitationList()
,因为您最终会得到一个可以传递给 LINQ 等其他位的谓词。)When you use += or -= when delegate types, that just gives a call to
Delegate.Combine
andDelegate.Remove
.The important thing about multicast delegates is that the return value of all but the last executed delegate is ignored. They all get executed (unless an exception is thrown), but only the last return value is used.
For predicates, you might want to do something like:
You'd then do:
EDIT: Here's a more general solution which is quite fun, if a bit bizarre...
So you could then implement And as:
(I personally prefer this over using
GetInvocationList()
, because you end up with a predicate you can pass to other bits of LINQ etc.)事实上,这是行不通的。 尝试用第一个条件失败但第二个条件通过的情况来测试它。 你会发现它会返回true。 原因是,在处理返回值的多播委托时,仅返回最后一个值。 例如:
这将返回 TRUE,因为最后一个函数调用返回 true(小于 20)。 为了真正使其工作,您需要调用:
它返回一个委托数组。 然后,您需要确保它们全部返回 true,以使最终结果为 true。 合理?
Actually, that doesn't work. Try to test it with a case where the first condition FAILS but the second one passes. You'll find that it'll return true. The reason is, because when dealing with multicast delegates that return values, only the last value is returned. For example:
This will return TRUE because the last function call returns true (it's less than 20). In order to really make it work, you need to call:
which returns an array of delegates. You then need to make sure they ALL return true, for the final result to be true. Make sense?
扩展 BFree 的答案(+1)
如果你想获得你正在寻找的行为,你需要将谓词显式地链接在一起。 这是一个例子
Expanding on BFree's answer (+1'd it)
If you want to get the behavior you're looking for, you'll need to explicitly chain the predicates together. Here is an example
如果你想组合谓词,试试这个;
你这样称呼它;
If you want to combine predicates, try this;
You call it like this;
+= 是专门实现的语法糖,用于支持向事件添加处理程序。 由于事件只是委托的一种特殊情况,并且 Func 也是委托,因此语法似乎可以在这里使用。
但你确定它能按预期工作吗? 我的意思是,您期望进行 AND 或 OR 评估吗? 如果你想要的话,你会如何实现相反的效果? 您确定它不只是返回第一个结果吗? 还是最后一个?
The += is syntactic sugar specifically implemented to support adding handlers to events. Since events are just a special case of delegate, and Func is also a delegate, the syntax appears to work here.
But are you sure it works as expected? By that I mean, do you expect an AND or OR evaluation? How would you implement the opposite if you wanted it? Are you sure it's not just returning the result of the first? Or the last?