委托: 谓词与动作与函数

有没有人能对这三位最重要的代表给出一个很好的解释(希望有例子) :

  • 说重点
  • 开拍
  • 有趣
36521 次浏览
  • Predicate: 本质上是 Func<T, bool>; 提出这样的问题: “指定的参数是否满足委托所表示的条件?”用于类似 List 的东西。FindAll.

  • 执行一个给定参数的动作。非常普遍的用途。在 LINQ 中没有多少使用,因为它基本上暗示了副作用。

  • Func: 在 LINQ 中使用 非常多,通常用于转换参数,例如通过将一个复杂的结构投影到一个属性。

其他重要代表:

  • EventHandler/EventHandler<T>: 在 WinForms 中使用

  • Comparison<T>: 类似于 IComparer<T>,但是是委托形式。

除了 Jon 的回答,还有

  • Converter<TInput, TOutput>: 本质上是 Func<TInput, TOutput>,但带有语义。由 List 使用。ConvertAll 和 Array。ConvertAll,但我个人从未在其他地方见过它。

MethodInvoker 是 WinForms 开发人员可以使用的; 它不接受任何参数,也不返回任何结果。它早于 Action,并且在调用 UI 线程时仍然经常使用,因为 BeginInvoke ()等人接受一个非类型委托; 尽管 Action 也可以做得很好。

myForm.BeginInvoke((MethodInvoker)delegate
{
MessageBox.Show("Hello, world...");
});

我还注意到了 ThreadStart 和 Parameter terizedThreadStart; 现在大多数人都会用 Action 替代它们。

谓词、 Func 和 Action 是。NET.每个委托实例都可以引用或指向具有特定签名的用户方法。

Action 委托-Action 委托实例可以指向接受参数并返回 void 的方法。

Func 委托-Func 委托实例可以指向接受变量数量参数并返回某种类型的方法。

谓词-谓词类似于 func 委托实例,它们可以指向采用可变参数数量并返回 bool 类型的方法。

ActionFuncPredicate都属于代表家族。

Action 可以接受 n 个输入参数,但返回 void。

Func 可以接受 n 个输入参数,但它总是返回所提供类型的结果。在 Func<T1,T2,T3,TResult>中,T1、 T2、 T3是输入参数,TResult 是它的输出。

Predicate: 谓词也是 Func 的一种形式,但它总是返回 bool。简单地说,它是 Func<T,bool>的包装器。

行动和功能与 lambda:

person p = new person();
Action<int, int> mydel = p.add;       /*(int a, int b) => { Console.WriteLine(a + b); };*/
Func<string, string> mydel1 = p.conc; /*(string s) => { return "hello" + s; };*/
mydel(2, 3);
string s1=  mydel1(" Akhil");
Console.WriteLine(s1);
Console.ReadLine();

Func 对 LINQ 比较友好,可以作为参数传入。(无点)

谓词不能,必须重新包装。

Predicate<int> IsPositivePred = i => i > 0;
Func<int,bool> IsPositiveFunc = i => i > 0;


new []{2,-4}.Where(i=>IsPositivePred(i)); //Wrap again


new []{2,-4}.Where(IsPositivePred);  //Compile Error
new []{2,-4}.Where(IsPositiveFunc);  //Func as Parameter

有关参数和返回每个类型的内容的简单示例

这个 Func 接受两个 int 参数并返回一个 int

 Func<int, int, int> sum = (a, b) => a + b;
Console.WriteLine(sum(3, 5));//Print 8

在本例中,func 没有参数,但返回一个字符串

Func<string> print = () => "Hello world";
Console.WriteLine(print());//Print Hello world

此操作接受两个 int 参数并返回 void

Action<int, int> displayInput = (x, y) => Console.WriteLine("First number is :" + x + " , Second number is "+ y);
displayInput(4, 6); //Print First number is :4 , Second number is :6

这个谓词只有一个参数,并且总是返回 bool。

Predicate<int> isPositive = (x) => x > 0;
Console.WriteLine(isPositive(5));//Print True

Action

文件:

封装没有参数且不返回值的方法。

使用 Action类型传递的函数必须返回 void,并且可以接受0到16个参数。
当您需要一个函数,该函数可以将 使用中的每个元素作为 什么的的容器,或者作为回调函数时,通常使用 Action

public void DoSomething(List<string> lines, Action<string> action)
{
foreach (string str in lines)
{
action(str);
}
}

Func

文件:

封装没有参数的方法,并返回由 TResult 参数指定的类型的值。

使用 Func类型传递的函数接受0到16个参数,并返回任何不是 void的类型。
当希望函数能够 修改或对容器中的每个元素执行某种操作时,通常使用 Func

//                                                 Parameter Types
//                                                     ▼▼▼  ▼▼▼
public List<int> DoMath(List<(int, int)> numbers, Func<int, int, int> operation)
//                                                               ▲▲▲
//                                                           Return Type
{
List<int> results = new();
foreach (var (left, right) in numbers)
{
out.Add(operation(left, right));
}
return out;
}

Predicate

文件:

表示定义一组条件并确定指定对象是否满足这些条件的方法。

使用 Predicate类型传递的函数必须返回 bool,并且必须正好接受 1参数。

接受 断言的函数的一个例子是像 AllAny这样的 LINQ 函数,如果对于列表中的元素的 所有/任何,所提供的谓词返回 true,则返回 true。

public void Example(string str)
{
// The char.IsLetter() function can be used as a predicate
//   because it takes 1 char as a parameter, and returns a bool.
//          ▼▼▼▼▼▼▼▼▼▼▼▼▼
if (str.All(char.IsLetter))
{
Console.WriteLine("All characters in the string are letters.");
}
}

比较

类型 报税表类别 最小参数 最大参数
Action void 0 16
Func 任何不 void的类型 0 16
Predicate bool 1 1

ActionFuncPredicate之间的唯一区别是它们作为参数返回和接受的类型; 它们都是委托,因此它们都表示作为参数传递的函数。

您可以在一行代码中创建自己的 delegate类型,并以与预先创建的类型相同的方式使用它们。

//         Accepts functions that return a decimal type, and...
//              ▼▼▼▼▼▼▼
public delegate decimal Operation(decimal left, decimal right);
//                                ▲▲▲▲▲▲▲       ▲▲▲▲▲▲▲
//                    ...take 2 parameters, both of type decimal.

你可在此了解更多有关代表的资料:
Https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/delegates/

简而言之,Func返回一个值,而 Action不返回任何值。

Func<int, string>——接受一个 int参数并返回一个 string参数。

Action<int, string>——接受两个参数: 一个 int参数和一个 string参数。

参考文献: https://tomisin.dev/blog/c-delegates-difference-between-func-and-action