您的位置:首页 > 编程语言 > C#

C#2.0中委托与匿名委托-引

2010-12-23 15:56 369 查看
在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();


[/code]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: