本篇是笔者在接触委托之后,揪掉了好几把头发之后,整理出来的笔记。
常见的传递对象是数据。委托的本质是为了把方法作为参数传递给其他方法。深层的用法和原理可以参考事件Event。
1. 完整的委托定义格式。
>>定义一个委托,准备相应的调用方法。注意:定义一个委托相当于定义一个新类,所有可以定义类的地方都可以定义委托。下面的代码定义在入口所在的类下面。
delegate double ProcessDelegate(double a, double b);//定义一个委托。 static double Multiply(double a, double b) { return a * b; } static double Divide(double a, double b) { return a / b; } static double Sum(double c, double d) { return c + d; }
>>在执行过程中调用这个委托:
static void Main(string[] args) { ProcessDelegate process;//申明ProcessDelegate的实例。 Console.WriteLine("Enter 2 numbers separated with a comma:"); string input = Console.ReadLine(); int commaPos = input.IndexOf(','); double a = double.Parse(input.Substring(0, commaPos)); double b = double.Parse(input.Substring(commaPos + 1, input.Length - commaPos - 1)); Console.WriteLine("Enter M to Multiply or D to Divide or S to Sum:"); input = Console.ReadLine(); if (input == "S") process = new ProcessDelegate(Sum);//委托赋值 else if (input == "M") process = new ProcessDelegate(Multiply);//委托赋值 else process = new ProcessDelegate(Divide);//委托赋值 Console.WriteLine("Result is {0}", process(a, b));//调用执行委托 Console.ReadKey(); }
优化一. 通过匿名委托简写代码。
优点:在上面1的基础上,可以不用定义委托的名称,代码稍微简洁一些。
上面的Multiply、Divide、Sum方法的代码一样,但是不需要定义ProcessDelegate。
代码为:
static double Multiply(double a, double b) { return a * b; } static double Divide(double a, double b) { return a / b; } static double Sum(double c, double d) { return c + d; } static void Main(string[] args) { Func<double, double, double> process;//直接申明一个匿名委托的实例。 Console.WriteLine("Enter 2 numbers separated with a comma:"); string input = Console.ReadLine(); int commaPos = input.IndexOf(','); double a = double.Parse(input.Substring(0, commaPos)); double b = double.Parse(input.Substring(commaPos + 1, input.Length - commaPos - 1)); Console.WriteLine("Enter M to Multiply or D to Divide or S to Sum:"); input = Console.ReadLine(); if (input == "S") process = new Func<double, double, double>(Sum);//委托赋值 //if (input == "S") process = Sum;//意义同上一行 else if (input == "M") process = new Func<double, double, double>(Multiply);//委托赋值 //else if (input == "M") process = Multiply;//意义同上一行 else process = new Func<double, double, double>(Divide);//委托赋值 //else process = Divide;//意义同上一行 Console.WriteLine("Result is {0}", process(a, b));//调用执行委托 Console.ReadKey(); }
与上述代码相比,不同的是打了下划线记号的几行代码,以及省略了ProcessDelegate的定义。
这是委托的第一步简写。
优化二. 匿名委托 + 匿名方法。
优点:不用定义委托的名称,也不用定义方法,代码更加简洁。
代码为:
static void Main(string[] args) { Func<double, double, double> process;//直接申明一个匿名委托的实例。 Console.WriteLine("Enter 2 numbers separated with a comma:"); string input = Console.ReadLine(); int commaPos = input.IndexOf(','); double a = double.Parse(input.Substring(0, commaPos)); double b = double.Parse(input.Substring(commaPos + 1, input.Length - commaPos - 1)); Console.WriteLine("Enter M to Multiply or D to Divide or S to Sum:"); input = Console.ReadLine(); if (input == "S") process = delegate(double x, double y) { return x + y; };//委托赋值 else if (input == "M") process = delegate(double x, double y) { return x * y; };//委托赋值 else process = delegate(double x, double y) { return x / y; };//委托赋值 Console.WriteLine("Result is {0}", process(a, b));//调用执行委托 Console.ReadKey(); }
同样注意下划线部分的代码。这种使用方法,在优化一的基础上用匿名方法替换了定义方法的代码。代码量更少。
优化三. lambda表达式。(关于lambda表达式的语法和具体用法,可以去问百度...)
优点:不用定义委托的名称,也不用定义方法,代码较第三种更简洁更直观。
代码为:
static void Main(string[] args) { Func<double, double, double> process;//直接申明一个匿名委托的实例。 Console.WriteLine("Enter 2 numbers separated with a comma:"); string input = Console.ReadLine(); int commaPos = input.IndexOf(','); double a = double.Parse(input.Substring(0, commaPos)); double b = double.Parse(input.Substring(commaPos + 1, input.Length - commaPos - 1)); Console.WriteLine("Enter M to Multiply or D to Divide or S to Sum:"); input = Console.ReadLine(); if (input == "S") process = (x, y) => x + y;//委托赋值 else if (input == "M") process = (x, y) => x * y;//委托赋值 else process = (x, y) => x / y;//委托赋值 Console.WriteLine("Result is {0}", process(a, b));//调用执行委托 Console.ReadKey(); }
与优化二使用方法相比,下面对process的赋值那里采用了lambda表达式,代码更简洁!
实际代码编写中,常用的格式是最后一种,也就是lambda表达式。可以看出来,格式的简化是一层一层步骤之后的结果。
本篇采用一层一层优化,辅以代码的方式。希望能给那些刚接触c#委托,以及对委托不太理解的难友一些提示和帮助。
//12.11.21新增代码文件。在网上下载的一个国外朋友的代码,加深匿名方法、lambda表达式、Func、Action的理解。
如果错误,请严肃纠正。
转发请注明本文地址:
http://www.cnblogs.com/icyJ/archive/2012/10/09/Delegate_Lambda.html