• 2分钟讲清楚C#的委托, C语言的函数指针,Java的函数式接口


    很多小伙伴学习C# 的委托时往往一头雾水, 不明白委托是什么, 有什么作用, 今天我就用2分钟讲清楚

    这是一个C# 的控制台程序
    定义一个最简单的委托 delegate int Calculate(int a, int b);

    这相当于定义了一个Calculate类型, 只不过这个类型需要传入2个int类型的参数
    返回值也是int

    委托的意义在于, 它可以将函数封装成可以像变量 int, string这样的类型传入到另外的函数中, 例如函数int Test(int a, int b, Calculate c)
    这大大提高了函数的功能和可扩展性, 可以在不改变Test函数的参数的同时,
    通过改变Calculate 来改变Test内部的逻辑关系

    namespace DelegateTest
    {
    
    
        public class Program
        {
    
            //定义一个Calculate 类型的委托
            delegate int Calculate(int a, int b); 
    
            static void Main(string[] args)
            {
                //定义一个返回值和参数都与Calculate相同的加法函数
                int Add(int a, int b)
                {
                    return a + b;
                }
                //定义一个返回值和参数都与Calculate相同的减法函数
                int Sub(int a, int b)
                {
                    return a - b;
                }
    
                //将委托类型calculate当参数传入函数
                int Test(int a, int b, Calculate calculate)
                {
                    return calculate(a, b) + a;
                }
    
                //委托的精髓在于, 将委托看作一种类型, 和int, String一样的类型.
                //只不过int a = b; 是将 int类型的变量 b 赋值给 a, 
                //而Calculate calculate1 = Sub; 是将Calculate类型的 Sub 赋值给 calculate1
                Calculate calculate1 = Sub; //定义一个Calculate 类型的calculate1字段, 并将Sub函数传递给它
                Calculate calculate2 = Add; //定义一个Calculate 类型的calculate2字段, 并将Add函数传递给它
    
                int i = Test(1, 2, calculate1); //返回 1 + (1+2) = 4
                int j = Test(1, 2, calculate2); //返回 1+  (1-2) = 0
    
                Console.WriteLine("i的值是:" + i);
                Console.WriteLine("j的值是:" + j);
            }
        }
    
    
    
    
    }
    
    • 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
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    很多人不知道, C# 的委托, 和C语言的函数指针是一个东西

    我们把C sharp的 delegate int Calculate(int a, int b)
    换成C语言的 typedef int (*Calculate)(int a, int b)

    // FunctionPoint.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
    //
    
    #include 
    
        //定义一个Calculate 类型的委托
      //delegate int Calculate(int a, int b); 
        typedef int (*Calculate)(int a, int b);
    
        //定义一个返回值和参数都与Calculate相同的加法函数
        int Add(int a, int b)
        {
            return a + b;
        }
        //定义一个返回值和参数都与Calculate相同的减法函数
        int Sub(int a, int b)
        {
            return a - b;
        }
    
        //将委托类型calculate当参数传入函数
        int Test(int a, int b, Calculate calculate)
        {
            return a + calculate(a, b);
        }
    
    int main()
    {
        //委托/函数指针的精髓在于, 将委托看作一种类型, 和int, String一样的类型.
        //只不过int a = b; 是将 int类型的变量 b 赋值给 a, 
        //而Calculate calculate1 = Sub; 是将Calculate类型的 Sub 赋值给 calculate1
        Calculate calculate1 = Add;
    
        Calculate calculate2 = Sub;
    
        int i = Test(1, 2, calculate1); //返回 1 + (1+2) = 4
        int j = Test(1, 2, calculate2); //返回 1+  (1-2) = 0
    
        printf("i的值是: %d\n", i);
        printf("j的值是: %d\n", j);
    }
    
    
    
    
    • 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
    • 42
    • 43
    • 44

    可以运行一下, 这两个程序返回的结果是一样的. 如果放在java 上怎么实现?

    函数式接口和委托, 函数指针是一脉相承的!

    package com.example.design;
    
    import org.junit.jupiter.api.Test;
    import org.springframework.boot.test.context.SpringBootTest;
    
    @SpringBootTest
    class DesignApplicationTests {
    
        //定义一个Calculate 类型的委托
        //delegate int Calculate(int a, int b);
        //typedef int (*Calculate)(int a, int b);
        @FunctionalInterface
        interface ICalculate{
            Integer Calculate (Integer a, Integer b);
        }
    
        //定义一个返回值和参数都与Calculate相同的加法函数
        Integer Add(Integer a, Integer b)
        {
            return a + b;
        }
        //定义一个返回值和参数都与Calculate相同的减法函数
        Integer Sub(Integer a, Integer b)
        {
            return a - b;
        }
    
        //将委托类型calculate当参数传入函数
        Integer Test(Integer a, Integer b, ICalculate iCalculate)
        {
            return a + iCalculate.Calculate(a, b);
        }
    
        @Test
        void contextLoads() {
            //委托/函数指针的精髓在于, 将委托看作一种类型, 和int, String一样的类型.
            //只不过int a = b; 是将 int类型的变量 b 赋值给 a,
            //而Calculate calculate1 = Sub; 是将Calculate类型的 Sub 赋值给 calculate1
            ICalculate calculate1 = this::Add;
            ICalculate calculate2 = this::Sub;
            Integer i = Test(1,2,calculate1);//返回 1 + (1+2) = 4
            Integer j = Test(1,2,calculate2);//返回 1+  (1-2) = 0
    
            System.out.println("i的值是:"+i);
            System.out.println("j的值是:"+j);
        }
    
    }
    
    
    • 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
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
  • 相关阅读:
    关于近期计划调整的通知
    Docker入门
    AcWing-C/C++语法基础【合集2】
    Redis(04)| 数据结构-压缩列表
    广电运通面试
    你了解Postman 变量吗?
    OS2.3.3:进程互斥的硬件实现方法
    官方图鉴解读丨透视小红书内容营销下半场
    基于 Bitbucket 的 CI/CD 在 Flutter 中的应用
    凯撒密码加解密过程与破解原理
  • 原文地址:https://blog.csdn.net/helldoger/article/details/132637795