Skip to content
FreeSql 官方文档FreeSql 官方文档
指南
扩展
服务支持
github icon
  • 指南

    • DB First
      • 表达式函数
        • 事务
          • 过滤器
            • ADO
              • AOP✨
                • 读写分离
                  • 分表分库
                    • 多租户
                      • 性能
                        • 你不知道的功能 ✨

                        author iconnicyecalendar icon2021年2月5日timer icon大约 4 分钟word icon约 1170 字

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

                        # 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

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

                        系统函数内置如下委托

                        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/5/16 下午8:50:28
                        贡献者: igeekfan,luoyunchong
                        Copyright © 2018-present nicye
                        Copyright © 2022 nicye

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

                        详情