FuncT TResult ActionT 和 PredicateT 委托类型

System 命名空间包含 Func<..., TResult> 委托类型,其中包含 0 到 15 个通用参数,返回类型 TResult

private void UseFunc(Func<string> func)
{
    string output = func(); // Func with a single generic type parameter returns that type
    Console.WriteLine(output);
}

private void UseFunc(Func<int, int, string> func)
{
    string output = func(4, 2); // Func with multiple generic type parameters takes all but the first as parameters of that type
    Console.WriteLine(output);
}

System 命名空间还包含具有不同数量的通用参数的 Action<...> 委托类型(从 0 到 16)。它类似于 Func<T1, .., Tn>,但它总是返回 void

private void UseAction(Action action)
{
    action(); // The non-generic Action has no parameters
}

private void UseAction(Action<int, string> action)
{
    action(4, "two"); // The generic action is invoked with parameters matching its type arguments
}

Predicate<T> 也是 Func 的一种形式,但它总会返回 bool。谓词是一种指定自定义条件的方法。根据输入的值和谓词中定义的逻辑,它将返回 truefalse。因此 Predicate<T> 的行为方式与 Func<T, bool> 相同,并且两者都可以以相同的方式初始化和使用。

Predicate<string> predicate = s => s.StartsWith("a");
Func<string, bool> func = s => s.StartsWith("a");

// Both of these return true
var predicateReturnsTrue = predicate("abc");
var funcReturnsTrue = func("abc");

// Both of these return false
var predicateReturnsFalse = predicate("xyz");
var funcReturnsFalse = func("xyz");

是否使用 Predicate<T>Func<T, bool> 的选择实际上是一个意见问题。Predicate<T> 可能更能表达作者的意图,而 Func<T, bool> 可能对更大比例的 C#开发者很熟悉。

除此之外,在某些情况下,只有一个选项可用,尤其是在与其他 API 交互时。例如 List<T>Array<T> 通常采用 Predicate<T> 作为他们的方法,而大多数 LINQ 扩展只接受 Func<T, bool>