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>
我的问题:Predicates
或Actions
是否有任何其他属性或品质可将其区分为Funcs
?
答案 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>
采用int
和float
,并返回一个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>
的参数的函数。但只要你一直使用其中一种,你就不会看到差异。