很多小伙伴学习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内部的逻辑关系
csharp
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);
}
}
}
很多人不知道, C# 的委托, 和C语言的函数指针是一个东西
我们把C sharp的 delegate int Calculate(int a, int b)
换成C语言的 typedef int (*Calculate)(int a, int b)
c
// FunctionPoint.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <stdio.h>
//定义一个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);
}
可以运行一下, 这两个程序返回的结果是一样的. 如果放在java 上怎么实现?
函数式接口和委托, 函数指针是一脉相承的!
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);
}
}