Predicates或Actions是否具有将它们区分为Funcs的任何其他属性或质量?

时间:2012-11-15 11:53:07

标签: c# .net delegates lambda functional-programming

Predicate只是一个Func,它返回一个布尔值:

Predicate<T1, T2, T3, ...,Tn> = Func<T1, T2, T3, ...,Tn, bool> 

Action只是Func,不会返回值:

Action<T1, T2, T3, ...,Tn> = Func<T1, T2, T3, ...,Tn, void>

我的问题PredicatesActions是否有任何其他属性或品质可将其区分为Funcs

4 个答案:

答案 0 :(得分:4)

Predicate只是bool返回类型的一种特殊形式的Func - 即。它与Func<X, bool>同构。

行动是完全不同的野兽。它说“这是一件可以做某事的事情”。用其他词语的动作会产生副作用。

Func和Predicate(可能至少)具有Referential Transparency的属性。它们可以表现为正确的数学函数。这就是说,对于一个Func a,它接受A类的元素并返回一个B,它应该总是为同一个A返回相同的B.这有一些相当深刻,重要且非常有用的属性 - 特别是它使它们非常易于测试,易于推理且易于编写。

另一方面,

动作必须执行副作用。副作用通常需要排序问题,难以撰写,并且是程序复杂性的重要来源。此外,他们避开类型系统,将这种复杂性隐藏在虚空之后。

Action和Func / Predicate根本就是截然不同的事情。

答案 1 :(得分:2)

不。没有任何。它们都只是委托类型。唯一的区别是某些方法采用Predicate<T>(主要是较旧的API),有些采用Func<> / Action<>Func<> / Action<>方法的一个优点是签名在名称中很明显(即Func<int,float,string>采用intfloat,并返回一个string),但就是。即使代理具有相同的签名,它们也不能直接互换(您不能将Func<T,bool>实例传递给采用Predicate<T>的方法。

答案 2 :(得分:1)

他们都是代表。代表不能声明任何特殊内容 - 它们实际上只是方法签名。

您无法向委托类型添加特殊功能 - 至少在C#中声明一个时也是如此。 (可以想象你可以在IL,但我从未见过这样做。)

答案 3 :(得分:1)

Action<T>Func<T, void>不同:前者有效,后者则无效。 void不是有效的泛型类型参数。

Predicate<T>Func<T, bool>表现完全相同。但是,它们仍然是不同的类型,因此您不能直接Predicate<T>传递给类型为Func<T, bool>的参数的函数。但只要你一直使用其中一种,你就不会看到差异。