Loading...
墨滴

莫激

2021/12/26  阅读:34  主题:橙心

c#中委托

委托

什么是委托

  • 委托是函数(方法)的容器
  • 可以理解为表示函数(方法)的变量类型
  • 用来存储、传递函数(方法)
  • 委托的本质是一个类,用来定义函数(方法)的类型(返回值和参数的类型)
  • 不同的函数(方法)必须对应和各自“格式”一直的委托

基本语法

  • 关键字 :delegate

  • 语法:访问修饰符 delegate 返回值 委托名(参数列表)

  • 写在哪里?

    可以申明在namespace和class语句块中

    更多的写在namespace中,所以委托也相当于一个类,在使用的使用也是更实例化一样写,比如:

    static void Main(string[] args)
    {
        Console.WriteLine("委托");
        MyFun f = new MyFun(a);//这就是委托,然后a里面写符合该委托规则的函数,a只需要写函数名
    }
  • 简单记忆委托语法

    函数申明语法前面加一个delegate关键字

定义自定义委托

  • 访问修饰默认不写,默认是public,写了private的话,在其他命名空间就不能用了

  • 申明了一个可以用来存储无参无返回值函数的容器

    //这些是定义在namespace中的,不是在class中的
    //这里只是定义了规则,并没有使用
    delegate void MyFun();

    //委托规则的申明 是不能重名(同一语句块中)

    delegate int MyFun(int a);

  • 申明一个用来装载或传递 返回值为int 有一个int参数的函数的委托容器规则

    public delegate int MyFun2(int a);

使用定义好的委托

delegate void MyFun();//定义了一个无参无返回值规则的委托
    
delegate int MyFun2(int a);//定义了int类型参数和int返回值规则的委托

class Program
{
    static void Main(string[]args)
 {
    //第一种装载函数方法,专门用来装载 函数 的容器
      MyFun f = new MyFun(Fun);//意思就是把Fun的函数装载在变量为f的委托上,注意前提是Fun函数必须得符合Myfun委托的规则,这里的MyFun的规则是无参无返回值,然后这一句只是把函数转载进去而已,并没有调用,在执行的时候是不会打印出Fun函数中的方法 
        Console.WriteLine("asdasd");
        Console.WriteLine("352455");//前面写这两条输出语句是为了表达,可以先把函数装载起来,等到要使用的时候,在如下一样用invoke进行调用
        f.Invoke(); //invoke实施的意思,这样才可以调用装载在f委托里的函数,
 } 
  
    //第二种装载函数的方法(一般采取第二种较多)
    MyFun f2 = Fun;//这跟上面用new MyFun(Fun)是一样的
    f2();//这跟上面用f.Invake是一样的,
     static void Fun()
    {
        Console.WriteLine("123123");
    }
}

注意:1)在委托中装载函数时候,函数不要打括号,因为打括号就表明要调用该函数,委托只是想要装载你而已,等到需要到的时候再进行invoke调用

**总结:**1)装载函数不要打括号,因为是装载,不是调用

​ 2)装载好的委托调用方法:f.Invoke( ); 或者 f( );

​ 3)委托所装的函数规则要和委托的一致,规则是看返回值和参数列表,变量名不用一致,但类型要一致

  • 委托常用在:

    1、作为类的成员

    2、作为函数的参数

delegate void MyFun();
delegate int MyFun2(int a);

class Test
{
    public MyFun fun; //委托变量
    public MyFun2 fun2; //这里就体现了是类的成员
    
    public void TestFun(MyFun fun,Myfun2 fun2)//这里就体现了作为函数的参数
    {
        //先处理一些别的逻辑 当这些逻辑处理完了 再执行传入的函数
        int i= 1
        i *= 2;
        i += 2;
        fun();//执行
        fun2(i);//执行
        
        this.fun = fun;//先传进来,暂时不执行
        this.fun2 = fun2;//先传进来,暂时不执行
    }
    
    public void test1()//这个函数符合MyFun委托的规则,因此可以用该委托装载该函数
    {
        Console.WriteLine("这是一个函数");
    }
}

class Program
{
    static void Main(string[]args)
    {
        Test t = new Test();
        t.TestFun(a,b);//这里传入的是函数名,方法传给委托,就相当于委托装载方法了,记得不用传入的方法不用加括号,不然会报错
    }
      static void a()
    {
        Console.WriteLine("123123");
    }
      static void b()
    {
        Console.WriteLine("asdasd");
    }
}

总结:委托有个延迟执行的操作效果,如上述代码就是先执行

委托变量可以存储多个函数(也叫多播委托)

MyFun ff = a;
ff += a;//用+=存储多个函数
ff(); //执行效果是执行两次函数 
MyFun ff2 = a;
ff2 += b;
ff2();

执行效果:

123123
123123//这是ff结果
123123
asdasd//这是ff2结果

委托有个作用是在逻辑处理中先处理一些逻辑后,再批量处理委托中的事情

也可以这样写:

MyFun f = null
f += a;
f += b;//这样写好处是,先定义,后再传值,比如下面的函数

public void test(MyFun fun1,MyFun fun2)//传进来的是方法,不是传委托
{
 f += fun1;
 f += fun2;

  • 从容器中移除指定的函数
ff -= Fun;
ff();
  • 清空容器
ff = null
ff()
;//这样运行会报错
if(ff != null//可以用if语句去判断是不是空值
{
    ff();
}

系统定义好的委托

无参无返回值委托

  • 使用系统自带委托 需要引用using System;

  • public delegate void Action(); //这是系统已经申明好的,直接就行

    Action //无参无返回值委托

  • 使用方法

    Action action = Fun;
    action += Fun2;
    action();

无参有返回值泛型委托

  • public delegate T Func<out T>();

    Func<> //无参无返回值泛型委托

  • 使用方法

    Func<string> funcString = Fun3;
    Func<int> funcString = Fun4;
    static string Fun3()
    {
        return "";
    }
    static int Fun4()
    {
        return 1;
    }

n个参数有返回值的泛型委托

  • 可以传n个参数的 系统提供了1到16个参数的委托 直接用就行了

  • Action<int,string> action2 = Fun6;

  • 可以传n个参数的 并且有返回值的 系统也提供了16个委托

  • Func<int,string,char> fun2 = Fun2;

    上面的委托的返回值是char

**总结:**1、委托是支持 泛型的 可以让返回值和参数 可变 更方便我们的使用

2、Action是没有返回值的,Func是有返回值的,两者都有泛型,泛型数量有16个,然后泛型Func的返回值是最右边位置的

总结

  1. 简单理解 委托 就是装载、传递函数的容器而已
  2. 可以用委托变量 来存储函数或者传递函数的
  3. 系统其实已经提供了很多委托给我们用
  4. Action:没有返回值,参数提供了 0~16 个委托给我们用
  5. Func:有返回值,参数提供了 0~16个委托给我们用
  6. 实际上用委托的时候都是用系统自带的委托,不会自己去定义

练习

练习
练习
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 委托
{
    class dele
    {
        public Action action = null;
    }
    class Program
    {
        static void Main(string[] args)
        {
            dele de = new dele();
            de.action += zuofan;
            de.action += kaifan;
            de.action += guocheng;

             void zuofan()
            {
                Console.WriteLine("妈妈做饭");
            }
            void kaifan()
            {
                Console.WriteLine("妈妈开饭");
            }
            void guocheng()
            {
                Console.WriteLine("吃饭过程");
            }
            int str = int.Parse(Console.ReadLine());
            if (str == 1)
            {
                de.action();
            }
            else
            {
                Console.WriteLine("没啥");
            }
        }}}

莫激

2021/12/26  阅读:34  主题:橙心

作者介绍

莫激