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();

posted on 2010-12-23 15:56  xiaoxxy  阅读(5991)  评论(0编辑  收藏  举报

导航