自定义委托

本章主要记录委托的语法及使用,以及 匿名方法Lambda表达式 在委托中的运用。
【参考文章】《c# 图解教程》(第五版)

委托

委托是持有一个或多个方法的对象。与对象的区别是,可以执行委托。

如何使用委托

  1. 声明委托类型
  //关键字:delegate
  //返回类型:void
  //委托类型名称:MyDel
  //参数:int x
  delegate void MyDel(int x);
  1. 创建委托对象
//委托类型:MyDel
//变量:delVar
MyDel delVar, dVar;
  1. 给委托赋值:由于委托是引用类型,可以通过给它赋值来改变包含在委托变量中的引用。旧的委托对象会被垃圾回收器回收。
//方式一:
//实例方法:myInstObj.MyM1
delVar = new MyDel(myInstObj.MyM1); 
//静态方法:SClass.OtherM2
dVar = new MyDel(SClass.OtherM2);

//方式二:
delVar = myInstObj.MyM1;//创建委托对象并赋值
dVar = SClass.OtherM2;
delVar = SClass.OtherM2; //创建新的委托对象并赋值
  1. 组合委托:通过额外的运算符来创建一个新的委托。委托是恒定的。
MyDel delA = myInstObj.MyM1; //未改变
MyDel delB = SClass.OtherM2; //未改变
MyDel delC = delA + delB; //具有组合调用列表的新委托
//内存会为delC分配一块新区域,调用列表有新的myInstObj.MyM1、 SClass.OtherM2。
  1. 为委托添加方法:在执行 += 操作时,实际发生的时创建一个新的委托,其调用列表是左边的委托+右边方法的组合。然后将这个新的委托赋值给delVar。
  2. 从委托移除方法:若调用列表中的方法有多个实例,执行 -= 运算符将从列表最后开始搜索,并且移除第一个与方法匹配的实例。
MyDel delVar = inst.MyM1; //创建并初始化
delVar += SC1.m3; //在调用列表的底部增加方法
delVar += X.Act; //继续增加方法,所以目前delVar的调用列表里有3个方法
delVar -= SC1.m3; //从委托中移除方法,所以目前delVar的调用列表里有2个方法:inst.MyM1,X.Act
  1. 调用委托:调用空委托会抛出异常。可以通过检查委托是否等于null判断,如果调用列表为空,则委托为null。
MyDel delVar = inst.MyM1; 
delVar += SC1.m3;
delVar += X.Act; 

//方式1:像调用方法一样调用委托
if (null != delVar)
{
    delVar(55); //调用委托
}

//方式2:使用委托的Invoke方法
delVar?.Invoke(65); //使用Invoke和空条件运算符

无参+无返 委托demo

    //定义一个没有返回值,没有参数的委托类型
    delegate void PrintFunction();
    class Test
    {
        public void Print1()
        {
            Console.WriteLine("Print1 -- instance");
        }
        public static void Print2()
        {
            Console.WriteLine("Print2 -- static");
        }
    }
    class DelegateTestDemo
    {
        static void Main()
        {
            Test t = new Test();     //创建一个测试类实例
            PrintFunction pf;        //创建一个空委托
            pf = t.Print1;           //实例化并初始化该委托

            //给委托增加3个另外的方法
            pf += Test.Print2;
            pf += t.Print1;
            pf += Test.Print2;      //目前委托含有4个方法
            if (null != pf)         //确认委托有方法
            {
                pf();               //调用委托
            }
            else {
                Console.WriteLine("Delegate is empty");
            }
        }
    }
输出结果:
Print1 -- instance
Print2 -- static
Print1 -- instance
Print2 -- static

无参+有返 委托demo

    //定义一个有返回值,没有参数的委托类型
    delegate int MyDel();
    class MyClass
    {
        int intValue = 5;
        public int Add2()
        {
            intValue += 2;
            return intValue;
        }
        public int Add3()
        {
            intValue += 3;
            return intValue;
        }
    }
    class DelegateTestDemo
    {
        static void Main()
        {
            MyClass mc = new MyClass();   
            MyDel mDel = mc.Add2;           //创建并初始化该委托

            //给委托增加2个方法
            mDel += mc.Add3;
            mDel += mc.Add2;
            Console.WriteLine($"Value: {mDel()}");
        }
    }

输出结果:
Value: 12

有参+无返 委托demo

    //定义一个无返回值,有参数的委托类型
    delegate void MyDel(ref int x);
    class MyClass
    {
        public void Add2(ref int x)
        {
            x += 2;
        }
        public void Add3(ref int x)
        {
            x += 3;
        }
    }
    class DelegateTestDemo
    {
        static void Main()
        {
            MyClass mc = new MyClass();
            MyDel mDel = mc.Add2;           //创建并初始化该委托

            //给委托增加2个方法
            mDel += mc.Add3;
            mDel += mc.Add2;
            int x = 5;
            mDel(ref x);
            Console.WriteLine($"Value: { x }");
        }
    }
输出结果:
Value: 12

有参+有返 委托demo

    class DelegateTestDemo
    {
        //定义一个有返回值,有参数的委托类型
        delegate int OtherDel(int x);
        public static int Add20(int x)
        {
            return x + 20;
        }
        
        static void Main()
        {
            OtherDel oDel = Add20;           //创建并初始化该委托
            Console.WriteLine("{0}",oDel(5));
            Console.WriteLine("{0}", oDel(6));
        }
    }
输出结果:
25
26
posted @ 2025-06-21 16:11  JuneSolsticeYeah  阅读(8)  评论(0)    收藏  举报