zoukankan      html  css  js  c++  java
  • C#2.0中委托与匿名委托引

    在C#中使用一个类时,分两个阶段。首先需要定义这个类,即告诉编译器这个类由什么字段和方法组成。然后(除非只使用静态方法)实例化类的一个对象。使用委托时,也需要经过这两个步骤。首先定义要使用的委托,对于委托,定义它就是告诉编译器这种类型代表了哪种类型的方法,然后创建该委托的一个或多个实例。
        简单的理解,委托就是给方法签名指定名称。
        示例1:   
    public delegate stringMyDelegate();
        classProgram
        {
           static void Main(string[] args)
           {
               int num=3;
               MyDelegate Dele = new MyDelegate(num.ToString);
               Console.WriteLine("String is " + Dele());
               Console.Read();
           }
       }

       该示例中,定义了一个委托MyDelegate,该委托返回一个string类型,Main函数中对其进行了实例化,并使其引用变量num的ToString()方法,注意委托中所引用的是方法的名称,因此如果这么写:   

    MyDelegate Dele = newMyDelegate(num.ToString());

       这种写法是错误的,另该方法的参数及返回值必须与委托的定义相匹配,否则无法通过编译。

       以上示例是委托的一般应用,C#2.0中,引入了匿名委托,拷一段MSDN上的Sample

       示例2:计算员工奖金

       

       //  Define the delegatemethod.声明委托

       delegate decimal CalculateBonus(decimal sales);

       //Define an Employeetype. 建立员工类

       class Employee
        {
           public string name;
           public decimal sales;
           public decimal bonus;
           public CalculateBonus calculation_algorithm;
        }

       class Program
        {

           // Thisclass will define two delegates that perform acalculation.这个类将实例化两个委托以计算奖金

           // The first will be anamed method, the second an anonymousdelegate.第一个是指定方法的委托,第二个则是匿名委托

           // This isthe namedmethod.下面这个是第一个委托所指定的方法

           // It defines one possible implementation ofthe Bonus Calculationalgorithm.声明了一个可执行的奖金运算法则

           static decimal CalculateStandardBonus(decimal sales)
           {
               return sales / 10;
           }

           static void Main(string[] args)
           {

               // A value used in the calculation of thebonus.奖金计算中用到一个值            
               // Note: This local variable will become a"captured outervariable".这个局部变量会变成一个“被捕获的外部变量”。不懂。。
               decimal multiplier = 2;

               // This delegate is defined as a namedmethod.这个委托以一个具体方法名声明
               CalculateBonus standard_bonus = newCalculateBonus(CalculateStandardBonus);

               // This delegate is anonymous - there is nonamedmethod.这个委托是匿名委托-没有方法名
               // It defines an alternative bonuscalculationalgorithm.声明了一个可供选择的奖金计算法则(即两个委托均可计算)
               CalculateBonus enhanced_bonus = delegate(decimal sales) { returnmultiplier * sales / 10; };

               // Declare some Employeeobjects.实例化一些员工对象
               Employee[] staff = new Employee[5];

               // Populate the array ofEmployees.给员工类数组赋值
               for (int i = 0; i < 5; i++)
                   staff[i] = new Employee();
              
               // Assign initial values toEmployees.给实例化的员工对象赋初值
               staff[0].name = "Mr Apple";
               staff[0].sales = 100;
               staff[0].calculation_algorithm = standard_bonus;

               staff[1].name = "Ms Banana";
               staff[1].sales = 200;
               staff[1].calculation_algorithm = standard_bonus;

               staff[2].name = "Mr Cherry";
               staff[2].sales = 300;
               staff[2].calculation_algorithm = standard_bonus;

               //上面三个使用的是具体方法的委托

               staff[3].name = "Mr Date";
               staff[3].sales = 100;
               staff[3].calculation_algorithm = enhanced_bonus;

               staff[4].name = "Ms Elderberry";
               staff[4].sales = 250;
               staff[4].calculation_algorithm = enhanced_bonus;

               //上面两个使用的是匿名委托

               // Calculate bonus for all Employees为所有的员工计算奖金
               foreach (Employee person in staff)
                   PerformBonusCalculation(person);

               // Display the details of all Employees显示员工详细资料
               foreach (Employee person in staff)
                   DisplayPersonDetails(person);
               test3();
               Console.Read();


           }

           public static void PerformBonusCalculation(Employee person)
           {

               // This method uses the delegate stored inthe personobject      

                //to perform thecalculation.这个方法执行储存在员工具体信息中的委托来实现计算

               // Note: This method knows about the multiplier local variable,even though
               // that variable is outside the scope of this method.
               // The multipler varaible is a "captured outer variable".注意:此方法可识别增加的局部变量,即使变量在该方法范围之外,增加的变量为“被捕获的外部变量”头晕。。不就是具体参数具体实现么,说的那么复杂。。
               person.bonus = person.calculation_algorithm(person.sales);
           }

           public static void DisplayPersonDetails(Employee person)
           {
               Console.WriteLine(person.name);
               Console.WriteLine(person.bonus);
               Console.WriteLine("---------------");
           }

    }

        通过上面这个例子我们可以看到匿名委托是如何定义及使用的,匿名委托的更有用的特性是可以访问当前上下文的变量,我们知道在之前的C#中,委托只能通过参数访问上下文变量,而在方法内访问外部变量是非法的,下面举个例子:

        示例3:

    delegate void TheEvent(int a);

    public static void test()
    {
     int x = 12;
     int y = 32;
     TheEvent ev = delegate(int a)
     { Console.WriteLine("output x+ y : {0}", x + y); };
     ev(x);
    }

    3.0 及更高版本中,Lambda 表达式取代了匿名方法,作为编写内联代码的首选方式。
    不使用匿名方法:
    Thread thread = new Thread(new ThreadStart(Run));  
    // 或 Thread thread = new Thread(Run); 
     thread.Start();
    使用匿名方法:
     Thread thread = new Thread(delegate()  {    // 要运行的代码  }); 
     // 或 Thread thread = new Thread(new ThreadStart(delegate()  
    {  
    // 要运行的代码  //
    })); 
     thread.Start();}
    使用Lambda 表达式:
    Thread thread = new Thread(() =>  {    // 要运行的代码  });  
    // 或 Thread thread = new Thread(new ThreadStart(() =>  {   // 要运行的代码  //})); 
     thread.Start();

  • 相关阅读:
    解决 Cordova 打包 vue项目为 APP 后,在安卓平台下 touchMove 事件不生效的问题
    解决微信内置浏览器里,下拉无法捕获 touchEnd 事件
    记录 React-native 项目中的各种坑坑
    内存型游戏外挂讲解
    浅谈数据抓取的几种方法
    php链表笔记:合并两个有序链表
    php链表笔记:链表的检测
    php链表笔记:单链表反转
    使用UUID和int自增主键的区别
    lumen框架使用Elasticsearch详解
  • 原文地址:https://www.cnblogs.com/xiaoxxy/p/1914963.html
Copyright © 2011-2022 走看看