C#委托(一)

本文介绍了C#中的委托,将其与C/C++的函数指针进行对比,并详细讲解了Action和Func两类常见委托的使用,同时阐述了如何自定义委托。通过实例展示了委托在无返回值和有返回值函数调用中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.委托是什么

个人理解:委托大概就跟现实生活中的委托差不多吧,举个栗子
	我想要买水果			(函数的操作),
	但是我不想或者不能亲自去买,
	所以我找了我弟弟		(委托类的实例),
	告诉他去干什么		(函数名给他),
	然后给他钱			(函数的参数),
	他不乐意的去买了		(函数的操作),
	然后他拿回来一颗桃子	(返回值);

1.1 C/C++中的函数指针

  • 一个函数在内存中实际上是一组机器语言指令的集合
  • 函数指针是一个指针变量,里面保存了函数这组机器语言指令的入口地址;
  • 先声明函数指针类型,参数类型要和函数的参数类型相同;
  • 声明函数指针类型的变量,将函数的入口地址赋给它;
  • 通过函数指针来调用函数。

实例:

#include <stdio.h>

typedef int (* Calc)(int a, int b);	//Calc是返回值为int,参数为(int, int)的函数指针

int Add(int a, int b)
{
	return a + b;
}

int Sub(int a, int b)
{
	return a - b;
}

int main()
{
	int x = 20, y = 30, z = 0;
	Calc func1 = &Add;	//取Add函数的地址
	Calc func2 = &Sub;	//取Sub函数的地址
	
	//正常方式调用函数
	printf("正常方式调用函数\n");
	z = Add(x, y);
	printf("%d + %d = %d\n", x, y, z);
	z = Sub(x, y);
	printf("%d - %d = %d\n", x, y, z);
	
	//函数指针方式调用
	z = 0;
	printf("函数指针的方式调用函数\n");
	z = func1(x, y);
	printf("%d + %d = %d\n", x, y, z);
	z = func2(x, y);
	printf("%d - %d = %d\n", x, y, z);
		
    scanf_s("%d", &z);	 //为了使程序停在这
	return 0;
}

1.2 C#中的委托

  • 委托是由C/C++的函数指针升级而来;
  • 是把一个函数名交给委托类的实例,通过委托类来调用这个函数;
  • 它跟函数指针的用法类似,都是通过传递函数的地址,让CPU通过地址来调用函数
  • 需要的参数也与函数的参数相同
  • 与C/C++不同的是:需要声明委托的实例,即new一个委托类的对象Function,把函数名传进去;
  • 通过new出来的这个委托的对象调用函数:Function.invoke()

2.委托的分类以及使用

C#已经为我们封装好了几种委托,其中常用的就是Action和Func

2.1 Action委托

  • Action是 没有返回值 的委托,它是一个类,可以用来调用 返回值为Void 的函数;
  • 使用时new一个Action的实例,将要调用的方法名传递给它;
  • 注意:方法名不要加上括号,加括号是函数调用。
using System;

namespace DelegateTest
{
  class Program
  {
     static void Main(string[] args)
     {
        Calculator calculator = new Calculator();
        //Action实例
        Action Act1 = new Action(calculator.OutPut);

        //通过正常方法调用
        calculator.OutPut();
        //通过委托的方法调用
        Act1.Invoke();

        Console.ReadKey();
     }
  }

  class Calculator
  {
     public void OutPut()
     {
        Console.WriteLine("I have 3 mathods");
     }
  }
}

这个程序输出了两行 I have 3 mathods ;

2.2 Func委托

  • Func和Action的区别:Func是有返回值的
  • 声明Func的时候需要在Func< >的尖括号中添加函数的参数类型,在最后加上返回值的类型
  • 例程如下:
using System;

namespace DelegateTest
{
  class Program
  {
     static void Main(string[] args)
     {
        Calculator calculator= new Calculator();
        int c = 0;

   		//前两个int是函数的参数类型,第三个int是函数的返回值类型
        Func<int, int, int> Function1 = new Func<int, int, int>(calculator.Add);	
        Func<int, int, int> Function2 = new Func<int, int, int>(calculator.Sub);

        //用委托的方式调用
        c = Function1.Invoke(1, 2);
        Console.WriteLine(c);
        c = Function2.Invoke(1, 2);
        Console.WriteLine(c);

        //正常方式调用
        c = 0;
        c = calculator.Add(100, 200);
        Console.WriteLine(c);
        c = calculator.Sub(100, 200);
        Console.WriteLine(c);

        Console.ReadKey();
     }
  }

  class Calculator
  {
     public int Add(int a, int b)
     {
        return a + b;
     }

     public int Sub(int a, int b)
     {
        return a - b;
     }
  }
}

通过输出的结果来看,两种调用方法的效果是相同的。

2.3 自定义委托 delegate

  • 除了使用C#给我们提供的委托,我们还可以自己定义一个delegate类;
  • 委托定义的方式与普通的类稍有区别;
  • 格式大致如此: public delegate 返回值类型 类名 (参数列表);
  • 例如:public delegate double calc(double x, double y);
  • 注意:参数和返回值必须与函数的相同
using System;

namespace DelegateTest
{
 public delegate double Calc(double x, double y);   //委托类的声明

 class Program
 {
    static void Main(string[] args)
    {
       Calculator calculator = new Calculator();

       Calc calc1 = new Calc(calculator.Add);
       Calc calc2 = new Calc(calculator.Sub);
       Calc calc3 = new Calc(calculator.Mul);
       Calc calc4 = new Calc(calculator.Div);

       double x = 100;
       double y = 200;
       double c = 0;

       c = calc1(x, y);
       Console.WriteLine(c);
       c = calc2(x, y);
       Console.WriteLine(c);
       c = calc3(x, y);
       Console.WriteLine(c);
       c = calc4(x, y);
       Console.WriteLine(c);

       Console.ReadKey();
    }
 }

 class Calculator
 {
    public double Add(double a, double b)
    {
       return a + b;
    }

    public double Sub(double a, double b)
    {
       return a - b;
    }

    public double Mul(double a, double b)
    {
       return a * b;
    }

    public double Div(double a, double b)
    {
       return a / b;
    }
 }
}

3 总结

  初步的学习了一下委托是什么,怎么使用;
  对于具体的使用场景,为什么使用它,还有使用它的好处,注意事项等等 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值