c# 进阶 委托

本文详细介绍了C#中的委托概念,包括其作为函数容器的特性,定义和使用自定义委托的语法,以及系统预定义的Action和Func委托。文中通过实例展示了如何存储和传递函数,以及如何实现多播委托,即一个委托变量可以存储多个函数。此外,还讨论了委托在实际编程中的应用,如在事件处理中的作用。
摘要由CSDN通过智能技术生成
using System;

namespace Lesson12_委托
{
    #region 知识点一 委托是什么
    //委托是函数的容器
    //可以理解为方法表示函数(方法)的变量类型
    //用来存储、传递函数(方法)
    //委托的本质是一个类,用来定义函数(方法)的类型(返回值和参数的类型)
    //不同的 函数(方法)必须对应和各自“格式”一致的委托
    #endregion

    #region 知识点二 基本语法
    //关键字:delegate
    //语法:访问修饰符 delegate 返回值 委托名(参数列表);

    //写在哪里?
    /* 可以声明在namespace或class语句块中
     * 更多的是写在namespace中
     *
     * 简单记忆委托语法:函数声明前加一个delegate关键字
     */
    #endregion

    #region 知识点三 定义自定义委托
    /* 访问修饰符默认不写时,为public,在引用命名空间后可以使用
     * private,其他命名空间就不能使用了
     * 一般使用public
     */

    //声明了一个可以用来存储无参无返回值函数的容器
    //这里只是定义了规则,未使用
    public delegate void Myfun();

    //委托规则的声明,是不能同名的(同一语句块中)
    //表示用来装载或传递:返回值为int,有一个int参数的函数的 委托 容器规则
    public delegate int Myfun2(int a);

    //声明泛型委托, 可以让返回值和参数类型可变
    //一般不自己声明,一般使用系统自带委托
    public delegate T Myfun3<T, K>(T t, K k);
    #endregion

    #region 知识点四 使用定义好的委托
    /* 委托变量是函数的容器
     *
     * 委托常用在:
     * 1.作为类的成员
     * 2.作为函数的参数
     */
    class Test
    {
        public Myfun fun;
        public Myfun2 fun2;
        public void TestFun(Myfun _fun, Myfun2 _fun2)
        {
            //先处理一些别的逻辑,当这些逻辑处理完了,在执行传入的函数
            int i = 1;
            i *= 2;
            i += 2;

            //_fun();
            //_fun2(1);
            this.fun = _fun;
            this.fun2 = _fun2;
        }

        #region 增
        public void AddFun(Myfun fun, Myfun2 fun2)
        {
            this.fun += fun;
            this.fun2 += fun2;
        }
        #endregion

        #region 删
        public void RemoveFun(Myfun fun, Myfun2 fun2)
        {
            this.fun -= fun;
            this.fun2 -= fun2;
        }
        #endregion
    }
    #endregion

    #region 知识点五 委托变量可以存储多个函数(多播委托)

    #region 增
    /* public void AddFun(Myfun fun, Myfun2 fun2)
     {
         this.fun += fun;
         this.fun2 += fun2;
     }*/
    #endregion

    #region 删
    /*public void RemoveFun(Myfun fun, Myfun2 fun2)
    {
        this.fun -= fun;
        this.fun2 -= fun2;
    }*/
    #endregion

    #endregion

    #region 知识点六 系统定义好的委托
    //系统提供了很多常用委托

    #endregion

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("委托");
            #region 知识点四 使用定义好的委托
            //专门用来 装载函数的 容器
            Myfun f = new Myfun(Fun);
            //使用,必须和委托声明时的规则一致
            //通过Invoke调用
            f.Invoke();
            Myfun f2 = Fun;
            f2.Invoke();
            //f2 = Fun2; error Fun2 没有与委托Myfun匹配的重载
            Myfun2 f3 = Fun2;
            //像函数一样调用
            Console.WriteLine(f3(1));

            Myfun2 f4 = new Myfun2(Fun2);
            Console.WriteLine(f4.Invoke(10));

            Test t = new Test();
            t.TestFun(Fun, Fun2);
            #endregion

            #region 知识点五 委托变量可以存储多个函数(多播委托)

            #region 增
            Console.WriteLine("***********增**************");
            //如何用委托存储多个函数
            Myfun ff = null;    //委托可以有初始null值
            ff += Fun;
            ff += Fun3;
            ff();
            t.AddFun(Fun, Fun2);
            t.fun();
            t.fun2(10);
            #endregion

            Console.WriteLine("*************删**************");
            #region 删
            /* 注意,委托为赋初始值不可使用
                Myfun ff2;
                ff2 += Fun; //error
            */

            /* 注意:委托赋初始值为null,删除不会报错,但是无处理
             * Myfun ff3 = null;
             * ff3 -= Fun;
             */
            //从容器中删除指定函数
            ff -= Fun;
            ff -= Fun;  //多减,不会报错,但是无处理
            ff();
            //清空容器
            ff = null;
            if (ff != null)
            {
                ff();
            }
            #endregion

            #endregion

            #region 知识点六 系统定义好的委托
            //系统提供了很多常用委托
            //需要引用using System;

            //Action 委托
            //封装一个方法,该方法不具有参数且不返回值。
            //public delegate void Action();
            Action action = Fun;
            action += Fun3;
            action();

            //Func<TResult> 委托
            //封装一个方法,该方法不具有参数,且返回由 TResult 参数指定的类型的值。
            //public delegate TResult Func<out TResult>();
            //out 表示返回值
            Func<string> funcString = Fun4;
            Func<int> funcInt = Fun5;

            //Action<T> 委托
            //封装一个方法,该方法只有一个参数并且不返回值。
            //public delegate void Action<in T>(T obj);
            //in 表示传入参数
            //共有16个重载,即可以传递16个参数
            Action<int, string, bool> actionN = Fun6;

            //Func<T, TResult> 委托
            //封装一个方法,该方法具有一个参数,且返回由 TResult 参数指定的类型的值。
            //public delegate TResult Func<in T,out TResult>(T arg);
            //共有17个重载,即可以传递16个参数,有一个返回值
            Func<int, int> func2 = Fun2;
            #endregion

            #region pratice-1
            Action familyDinner = null;
            familyDinner += MotherCook;
            familyDinner += FatherEat;
            familyDinner += SonEat;
            familyDinner();
            #endregion

            Console.WriteLine("*******pratic-2******");

            #region pratice-2
            Action updateAcchieve = null;
            updateAcchieve += MonsterDead;
            updateAcchieve += PlayerCoinAdd;
            updateAcchieve += Update;
            updateAcchieve += AchievementChange;
            updateAcchieve();
            #endregion
        }

        #region 函数
        public static void Fun6(int a, string b, bool c)
        {
            Console.WriteLine("委托存储的Fun6函数,有多个参数");
        }

        static public int Fun5()
        {
            Console.WriteLine("委托存储的Fun5函数");
            return -1;
        }

        static public string Fun4()
        {
            Console.WriteLine("委托存储的Fun4函数");
            return "";
        }
        static public void Fun()
        {
            Console.WriteLine("委托存储的Fun函数");
        }

        static public void Fun3()
        {
            Console.WriteLine("委托存储的Fun3函数");
        }

        public static int Fun2(int num)
        {
            Console.WriteLine("委托存储的Fun2函数");
            return num;
        }
        #endregion

        #region pratice-1
        public static void MotherCook()
        {
            Console.WriteLine("Monther cooks");
        }
        public static void FatherEat()
        {
            Console.WriteLine("Father eat");
        }
        public static void SonEat()
        {
            Console.WriteLine("Son eat");
        }
        #endregion

        #region pratice-2
        public static void MonsterDead()
        {
            Console.WriteLine("MonsterDead");
        }
        public static void PlayerCoinAdd()
        {
            Console.WriteLine("PlayerCoinAdd Ten");
        }
        public static void Update()
        {
            Console.WriteLine("Update");
        }

        public static void AchievementChange()
        {
            Console.WriteLine("AchievementChange");
            AddMonsterKill();
        }

        public static void AddMonsterKill()
        {
            Console.WriteLine("AddMonsterKill");
        }
        #endregion
    }
}
/* 总结
* 委托:就是装载、传递函数的容器
* 可以用委托变量,来存储函数或传递函数
* C#已经定义好了很多委托,Action和Func
* Action:无返回值,16个重载,即可以最多可以传递16个参数
* Func:有返回值,17个重载,即最多可以传递16个参数和一个返回值
*/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值