APredicate
只是 aFunc
返回一个布尔值:
Predicate<T1, T2, T3, ...,Tn> = Func<T1, T2, T3, ...,Tn, bool>
而 anAction
只是 aFunc
不返回值:
Action<T1, T2, T3, ...,Tn> = Func<T1, T2, T3, ...,Tn, void>
我的问题:是否Predicates
或Actions
有任何额外的属性或品质来区分它们Funcs
?
APredicate
只是 aFunc
返回一个布尔值:
Predicate<T1, T2, T3, ...,Tn> = Func<T1, T2, T3, ...,Tn, bool>
而 anAction
只是 aFunc
不返回值:
Action<T1, T2, T3, ...,Tn> = Func<T1, T2, T3, ...,Tn, void>
我的问题:是否Predicates
或Actions
有任何额外的属性或品质来区分它们Funcs
?
Predicate 只是用于 bool 返回类型的 Func 的一种特殊形式——即。它同构于Func<X, bool>
。
不过,动作是完全不同的野兽。它说“这是一件可以做某事的事情”。换句话说,Action 将执行副作用。
Func 和 Predicate (可能至少)具有引用透明度的属性。它们可以表现为适当的数学函数。这就是说,对于接受类型 A 的元素并返回 B 的 Func a,它应该总是为同一个 A 返回相同的 B。这具有一些相当深刻、重要和非常有用的属性——特别是它使它们非常易于测试,非常易于推理且易于编写。
另一方面,动作必须执行副作用。副作用通常涉及排序问题,难以组合,并且是程序复杂性的重要来源。此外,他们回避类型系统,将这种复杂性隐藏在 void 后面。
Action 和 Func/Predicate 是根本不同的东西。
没有。没有任何。它们都只是委托类型。唯一的区别是有些方法采用类似的东西Predicate<T>
(主要是较旧的 API),有些采用Func<>
/ Action<>
。Func<>
/方法的一个优点Action<>
是签名从名称中显而易见(即 aFunc<int,float,string>
接受 anint
和 afloat
并返回 a string
),但仅此而已。即使委托具有相同的签名,它们也不能直接互换(您不能将Func<T,bool>
实例传递给采用 的方法Predicate<T>
)。
他们都只是代表。代表不能声明任何特殊的东西——它们实际上只是方法签名。
您不能向委托类型添加特殊功能 - 至少在 C# 中声明一个时。(可以想象,你可以在 IL 中,但我从未见过这样做。)
Action<T>
不一样Func<T, void>
:前者有效,后者无效。void
不是有效的泛型类型参数。
Predicate<T>
并且Func<T, bool>
行为完全相同。但是,它们仍然是不同的类型,因此您不能直接将 a 传递Predicate<T>
给带有 type 参数的函数Func<T, bool>
。但是,只要您始终使用其中一种,您就不会看到差异。