zoukankan      html  css  js  c++  java
  • 委托(delegate)

    委托dekegate是一种动态调用方法的类型,与类、接口和数组相同,属于引用型,可以用来实现多路广播(MulticastDelegate)。

    多路广播(MulticastDelegate):可以用"+""-"将多个委托对象合并、移除,可以使用"+="添加委托对象,"-="移除委托对象。

     

    委托的特点:

    1)委托类似于C++函数指针,但与指针不同的是,委托是完全面向对象的,是安全的数据类型;

    2)委托允许将方法作为参数进行传递;

    3)委托可用于定义回调方法;

    4)委托可以把多个方法链接在一起。这样,在时间触发时,可同时启动多个时间处理程序。

    委托的声明:

    [访问修饰符] delegate 返回值类型 委托名([参数列表]);

     

    public delegate int Calculate (int x, int y);

     

    委托的实例化:

    委托类型 委托变量名 = new 委托型构造函数 (委托要引用的方法名)

     

    int Multiply (int x, int y)
    {
        return x * y;
    }
    
    int Add(int x, int y)
    {
        return x + y;
    } 
    
    Calculate a = new Calculate(Multiply);
    Calculate b = new Calculate(Add);
    Calculate c = new Calculate(); 
    
    c = a + b; //组合调用
    
    c += new Calculate(Add); //添加委托对象
    
    c -= a; //移除委托对象

     

    其中,a,b为委托型对象。

    由于实例化委托实际上是创建了一个对象,所以委托对象可以参与赋值运算,甚至作为方法参数进行传递。

     

    使用委托:

    Calculate calc = new Calculate(Add);
    
    int result = calc(3,6);

     

    这里calc相当于调用了Add方法。

    使用匿名方法:

    C# 2.0开始,引入了匿名方法的概念,允许将代码块作为参数传递,避免单独定义方法。

    委托类型 委托变量名 = delegate [ 参数列表 ]{代码块};

    using System;
    delegate void D(int x); //声明委托
    
    class C
    {
        public static void M1(int i) 
        {
            Console.WriteLine("C.M1: " + i);
        }
        public static void M2(int i) 
        {
            Console.WriteLine("C.M2: " + i);
        }
        public void M3(int i) 
        {
            Console.WriteLine("C.M3: " + i);
        }
    }
    class Test
    {
        static void Main() 
        { 
            D cd1 = new D( C.M1);
            cd1(-1);        // call M1
            Console.WriteLine();
            
            D cd2 = null;
            cd2 += new D( C.M2);
            cd2(-2);        // call M2
            Console.WriteLine();
            
            D cd3 = cd1 + cd2;
            cd3(10);        // call M1 then M2
            Console.WriteLine();
            
            cd3 += cd1;
            cd3(20);        // call M1, M2, then M1
            Console.WriteLine();
            
            C c = new C();  //委托相同与否的判断条件:函数体是否相同
            D cd4 = new D(c.M3);
            cd3 += cd4;
            cd3(30);        // call M1, M2, M1, then M3
            Console.WriteLine();
            
            cd3 -= cd1;       // remove last M1
            cd3(40);        // call M1, M2, then M3
            Console.WriteLine();
            
            cd3 -= cd4;
            cd3(50);        // call M1 then M2
            Console.WriteLine();
            
            cd3 -= cd2;        
            cd3(60);        // call M1
            Console.WriteLine();
            
            cd3 -= cd2;       // impossible removal is benign
            cd3(60);        // call M1
            Console.WriteLine();
            
            cd3 -= cd1;       // invocation list is empty
            Console.WriteLine( cd3 == null );
            
            //      cd3(70);    // System.NullReferenceException thrown
            cd3 -= cd1;       // impossible removal
            Console.WriteLine( cd3 == null );
            
            Console.ReadKey(true); 
        }
    }

    运行结果:

  • 相关阅读:
    SQL执行效率1
    php经典算法(转载)
    linux自用命令
    vim基本命令
    xampp安装
    BUU-rsa
    z3约束器学习笔记
    面试前夕oi挣扎式复习
    bss上的格式化字符串漏洞
    一、汇编
  • 原文地址:https://www.cnblogs.com/bincoding/p/4870151.html
Copyright © 2011-2022 走看看