Skip to content
.NET 开发者指北.NET 开发者指北
CMS
.NET指北
FreeKit
Docker
关于
博客
github icon
    • Blogs分享
      • git emoji
        • .NET+Sqlite 如何支持加密
          • .NET 编码的基础知识
            • C#委托的介绍
              • C#委托的介绍(delegate、Action、Func、predicate)
                • delegate
                  • Action
                    • Func
                      • Predicate
                        • 事件
                          • 参考
                          • 多个 IFreeSql实例,如何注入使用

                          C#委托的介绍

                          calendar icon2022年8月1日timer icon大约 4 分钟word icon约 1177 字

                          此页内容
                          • C#委托的介绍(delegate、Action、Func、predicate)
                          • delegate
                          • Action
                          • Func
                          • Predicate
                          • 事件
                          • 参考

                          # C#委托的介绍

                          # C#委托的介绍(delegate、Action、Func、predicate)

                          委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递。事件是一种特殊的委托。

                          类似 c++的函数指针,但是他是类型安全的,

                          1. 允许将方法作为参数传递。
                          2. 可用于定义回调方法。
                          3. 委托可以链接在一起。例如,可以对一个事件调用多个方法。

                          # delegate

                          委托的关键字是 delegate,一个委托相当于一个新的类,可使用访问修饰符 public、private、protected 等,作用域同类的修饰符.

                          定义了委托类型与参数,使得可以将方法当作另一个方法参数来传递。事件是一种特殊的委托。

                          Delegate 至少 0 个参数,至多 32 个参数,可以无返回值,也可以指定返回值类型。

                          定义一个委托,有二个参数,并返回 Int 类型的值。

                              delegate int CalculateMethodInvoker(int a, int b);
                          
                          1

                          定义方法,方法参数与返回值与委托保持一致

                              public class CalculateHelper
                              {
                                  public static int Sum(int x, int y)
                                  {
                                      return x + y;
                                  }
                                  public static int Multiply(int x, int y)
                                  {
                                      return x * y;
                                  }
                              }
                          
                          1
                          2
                          3
                          4
                          5
                          6
                          7
                          8
                          9
                          10
                          11

                          调用

                          class Program
                          {
                              static void Main(string[] args)
                              {
                                  CalculateMethodInvoker calculateSumInvoker = CalculateHelper.Sum;
                                  CalculateMethodInvoker calculateSumInvoker2 = new CalculateMethodInvoker(CalculateHelper.Sum);//实例化一个委托
                                  CalculateMethodInvoker calculateMultiplyInvoker = CalculateHelper.Multiply;
                          
                                  int x = 20, y = 10;
                          
                                  int addResult = calculateSumInvoker(x, y);
                                  int addResult2 = calculateSumInvoker2(x, y);
                                  int invokeResult = calculateSumInvoker.Invoke(x, y);
                          
                                  Console.WriteLine($"x,y相加,得到{addResult},{addResult2},{invokeResult}");
                                  Console.WriteLine($"x,y相乘,得到{calculateMultiplyInvoker(x,y)}");
                          
                                  Console.ReadKey();
                              }
                          }
                          
                          1
                          2
                          3
                          4
                          5
                          6
                          7
                          8
                          9
                          10
                          11
                          12
                          13
                          14
                          15
                          16
                          17
                          18
                          19
                          20

                          一个委托可以将多个方法链接在一起。也可以移除某个方法

                          public static void ContactDelegate()
                          {
                              CalculateMethodInvoker calculateInvoker = CalculateHelper.Sum;
                              calculateInvoker += CalculateHelper.Multiply;
                          
                              int r1 = calculateInvoker(10, 20);
                              Console.WriteLine($"ContactDelegate:{r1}");
                          
                              calculateInvoker -= CalculateHelper.Multiply;
                              int r2 = calculateInvoker(10, 20);
                              Console.WriteLine($"ContactDelegate:{r2}");
                          }
                          
                          1
                          2
                          3
                          4
                          5
                          6
                          7
                          8
                          9
                          10
                          11
                          12

                          # Action

                          Action 是无返回值的泛型委托。特点是:至少 0 个参数,至多 16 个参数,无返回值。

                          1. 调用方法、可以传入参数
                          public static void ActionParams()
                          {
                              Action<int, int> action = new Action<int, int>(Sum);
                              action(1, 2);
                          }
                          public static void Sum(int x, int y)
                          {
                              Console.WriteLine($"x+y={x + y}");
                          }
                          
                          1
                          2
                          3
                          4
                          5
                          6
                          7
                          8
                          9
                          1. 使用 lambda 表达式
                          public static void ActionLambda()
                          {
                              Action<int, int> action = (x, y) =>
                              {
                                  Console.WriteLine($"x+y={x + y}");
                              };
                              action(1, 2);
                          }
                          
                          1
                          2
                          3
                          4
                          5
                          6
                          7
                          8

                          # Func

                          Func 是有返回值的泛型委托,Func 特点:至少 0 个参数,至多 16 个参数,根据返回值泛型返回。必须有返回值,不可 void

                          Func<int> 表示无参,返回值为 int 的委托

                          Func<int, int, string> 表示传入参数为 int, int。 返回值为 string 的委托

                          1.调用方法,传入参数

                          public static void FuncMethod()
                          {
                              Func<int, int, int> fc1 = new Func<int, int, int>(CalculateHelper.Sum);
                              int result = fc1(1, 2);//调用委托
                              Console.WriteLine(result);
                          }
                          
                          1
                          2
                          3
                          4
                          5
                          6

                          2.使用 lambda

                          public static void FuncLambda()
                          {
                              Func<int, int, string> fc = (x, y) => { return (x + y).ToString(); };
                              string r = fc(1,2);
                              Console.WriteLine(r);
                          }
                          
                          1
                          2
                          3
                          4
                          5
                          6

                          # Predicate

                          predicate 是返回 bool 型的泛型委托

                          predicate<int> 表示传入参数为 int 返回 bool 的委托

                          Predicate 有且只有一个参数,返回值固定为 bool

                          1、使用单行 lambda,带括号的 lambda(可多行代码),独立的方法。都返回 bool 类型的值。

                          public static void PredicateBoolean()
                          {
                              Point[] points = {
                                          new Point(100, 200),
                                          new Point(150, 250),
                                          new Point(250, 375),
                                          new Point(275, 395),
                                          new Point(295, 450)
                                      };
                              Predicate<Point> predicate1 = p => p.X * p.Y > 100000;
                              Predicate<Point> predicate2 = p =>
                              {
                                  if (p.X * p.Y > 100000)
                                  {
                                      return true;
                                  }
                                  else
                                  {
                                      return false;
                                  }
                              };
                              Point first = Array.Find(points, ProductGT10);
                              Point p1 = Array.Find(points, predicate1);
                              Point p2 = Array.Find(points, predicate2);
                          
                              Console.WriteLine("Found: X = {0}, Y = {1}", first.X, first.Y);
                              Console.WriteLine("Found: X = {0}, Y = {1}", p1.X, p1.Y);
                              Console.WriteLine("Found: X = {0}, Y = {1}", p2.X, p2.Y);
                              Console.ReadKey();
                          }
                          private static bool ProductGT10(Point p)
                          {
                              if (p.X * p.Y > 100000)
                              {
                                  return true;
                              }
                              else
                              {
                                  return false;
                              }
                          }
                          
                          1
                          2
                          3
                          4
                          5
                          6
                          7
                          8
                          9
                          10
                          11
                          12
                          13
                          14
                          15
                          16
                          17
                          18
                          19
                          20
                          21
                          22
                          23
                          24
                          25
                          26
                          27
                          28
                          29
                          30
                          31
                          32
                          33
                          34
                          35
                          36
                          37
                          38
                          39
                          40
                          41

                          Array.Find 方法,使用 Predicate 委托搜索 Point 结构的数组,只有是 x 和 y 字段的乘积大于 100000,方法 ProductGT10 返回 true,找到符合要求的元素后停止。

                          # 事件

                          事件自身就是委托类型,由于委托可以绑定调用多个方法,这会给事件的处理带来方便 。类只需要对外公开事件,就可以与外部的其他地方关联,从而实现事件订阅。

                          1.由于不同的事件要传递的参数不同,我们通过继承 EventArgs,

                          public class KeyPressEventArgs : EventArgs
                          {
                              public ConsoleKey PressdKey { get; private set; }
                              public KeyPressEventArgs(ConsoleKey consoleKey)
                              {
                                  this.PressdKey = consoleKey;
                              }
                          }
                          
                          1
                          2
                          3
                          4
                          5
                          6
                          7
                          8

                          2.带有泛型参数的事件处理委托。

                          系统函数内置如下委托

                          public delegate void EventHandler<TEventArgs>(object sender,TEventArgs e);   TEventArgs 是一个泛型参数
                          
                          1
                          class App
                          {
                              public event EventHandler<KeyPressEventArgs> KeyPressed;
                              protected virtual void OnSpaceKeyPressed(KeyPressEventArgs e)
                              {
                                  KeyPressed?.Invoke(this, e);
                              }
                          
                              public void StartRun()
                              {
                                  while (true)
                                  {
                                      ConsoleKeyInfo keyInfo = Console.ReadKey();
                                      if (keyInfo.Key == ConsoleKey.Spacebar)
                                      {
                                          OnSpaceKeyPressed(new KeyPressEventArgs(keyInfo.Key));
                                      }
                          
                                      if (keyInfo.Key == ConsoleKey.Escape)
                                      {
                                          break;
                                      }
                                  }
                              }
                          }
                          
                          
                          1
                          2
                          3
                          4
                          5
                          6
                          7
                          8
                          9
                          10
                          11
                          12
                          13
                          14
                          15
                          16
                          17
                          18
                          19
                          20
                          21
                          22
                          23
                          24
                          25
                          26
                          class Program
                          {
                              static void Main(string[] args)
                              {
                                  Console.WriteLine("空格:输入当前时间");
                                  Console.WriteLine("ESC:退出系统");
                          
                                  App app = new App();
                                  app.KeyPressed += MyApp_SpaceKeyPressed;
                                  app.StartRun();
                              }
                          
                              public static void MyApp_SpaceKeyPressed(object sender,KeyPressEventArgs e)
                              {
                                  Console.WriteLine($"{DateTime.Now.ToLongTimeString()}按下空格键,{e.PressdKey.ToString()}");
                              }
                          }
                          
                          
                          1
                          2
                          3
                          4
                          5
                          6
                          7
                          8
                          9
                          10
                          11
                          12
                          13
                          14
                          15
                          16
                          17
                          18

                          # 参考

                          • C#委托的介绍(delegate、Action、Func、predicate)open in new window
                          • c# 定义委托和使用委托(事件的使用)open in new window
                          edit icon在 GitHub 上编辑此页open in new window
                          上次编辑于: 2022/8/1 13:27:15
                          贡献者: igeekfan
                          上一页
                          .NET 编码的基础知识
                          下一页
                          多个 IFreeSql实例,如何注入使用
                          MIT Licensed | Copyright © 2021-present luoyunchong
                          苏ICP备16046457号-1

                          该应用可以安装在你的 PC 或移动设备上。这将使该 Web 应用程序外观和行为与其他应用程序相同。它将在出现在应用程序列表中,并可以固定到主屏幕,开始菜单或任务栏。此 Web 应用程序还将能够与其他应用程序和你的操作系统安全地进行交互。

                          详情