注:看红字部分


1. 委托Delegate

C#中的Delegate对应于C中的指针,但是又有所不同C中的指针既可以指向方法,又可以指向变量,并且可以进行类型转换,

C中的指针实际上就是内存地址变量,他是可以直接操作内存的,通过内存地址直接访问变量,直接调用方法。

而C#中的Delegate是强类型的,也就是说在声明委托时就已经指定了该变量只能指向具有特定参数,以及返回值的方法。

    使用delegate就可以直接建立任何名称的委托类型,当进行系统编译时,系统就会自动生成此类型。您可以使用delegate void MyDelegate() 

方式建立一个委托类,并使用ILDASM.exe观察其成员。由ILDASM.exe 中可以看到,它继承了System.MulticastDelegate类,

并自动生成BeginInvoke、EndInvoke、Invoke 等三个常用方法。

C# 委托、事件,lamda表达式_操作符

Invoke 方法是用于同步调用委托对象的对应方法,而BeginInvoke、EndInvoke是用于以异步方式调用对应方法的。


1 2 3 4 5 6 7 8

​public​​​​class​​​​MyDelegate:MulticastDelegate​​​​​​​​{​​​​​​​​//同步调用委托方法​​​​​​​​public​​​​virtual​​​​void​​​​Invoke();​​​​​​​​//异步调用委托方法​​​​​​​​public​​​​virtual​​​​IAsyncResult BeginInvoke(AsyncCallback callback,​​​​object​​​​state);​​​​​​​​public​​​​virtual​​​​void​​​​EndInvoke(IAsyncResult result);​​​​​​​​}​


MulticastDelegate是System.Delegate的子类,它是一个特殊类,编译器和其他工具可以从此类派生,但是自定义类不能显式地从此类进行派生。它支持多路广播委托,并拥有一个带有链接的委托列表,在调用多路广播委托时,系统将按照调用列表中的委托出现顺序来同步调用这些委托。

MulticastDelegate具有两个常用属性:Method、Target。其中Method 用于获取委托所表示的方法Target 用于获取当前调用的类实例。


1.1 委托的使用

当建立委托对象时,委托的参数类型必须与委托方法相对应。只要向建立委托对象的构造函数中输入方法名称example.Method,委托就会直接绑定此方法。使用myDelegate.Invoke(string message),就能显式调用委托方法。但在实际的操作中,我们无须用到 Invoke 方法,而只要直接使用myDelegate(string message),就能调用委托方法。

无返回值的委托


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

​class​​​​Program​​​​​​​​{​​​​​​​​delegate​​​​void​​​​MyDelegate(​​​​string​​​​message);​​​​​​​​​​​​public​​​​class​​​​Example​​​​​​​​{​​​​​​​​public​​​​void​​​​Method(​​​​string​​​​message)​​​​​​​​{​​​​​​​​MessageBox.Show(message);​​​​​​​​}​​​​​​​​}​​​​​​​​​​​​static​​​​void​​​​Main(​​​​string​​​​[] args)​​​​​​​​{​​​​​​​​Example example=​​​​new​​​​Example();​​​​​​​​MyDelegate myDelegate=​​​​new​​​​MyDelegate(example.Method);​​​​​​​​myDelegate(​​​​"Hello World"​​​​);​​​​​​​​Console.ReadKey();​​​​​​​​}​​​​​​​​}​


有返回值的委托


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23

​class​​​​Program​​​​​​​​{​​​​​​​​delegate​​​​string​​​​MyDelegate(​​​​string​​​​message);​​​​​​​​​​​​public​​​​class​​​​Example​​​​​​​​{​​​​​​​​public​​​​string​​​​Method(​​​​string​​​​name)​​​​​​​​{​​​​​​​​return​​​​"Hello "​​​​+ name;​​​​​​​​}​​​​​​​​}​​​​​​​​​​​​static​​​​void​​​​Main(​​​​string​​​​[] args)​​​​​​​​{​​​​​​​​Example example=​​​​new​​​​Example();​​​​​​​​//绑定委托方法​​​​​​​​MyDelegate myDelegate=​​​​new​​​​MyDelegate(example.Method);​​​​​​​​//调用委托,获取返回值​​​​​​​​string​​​​message = myDelegate(​​​​"Leslie"​​​​);​​​​​​​​Console.WriteLine(message);​​​​​​​​Console.ReadKey();​​​​​​​​}​​​​​​​​}​



多路广播委托


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

​delegate​​​​double​​​​MyDelegate(​​​​double​​​​message);​​​​​​​​​​​​public​​​​class​​​​Price​​​​​​​​{​​​​​​​​public​​​​double​​​​Ordinary(​​​​double​​​​price)​​​​​​​​{​​​​​​​​double​​​​price1 = 0.95 * price;​​​​​​​​Console.WriteLine(​​​​"Ordinary Price : "​​​​+price1);​​​​​​​​return​​​​price1;​​​​​​​​}​​​​​​​​​​​​public​​​​double​​​​Favourable(​​​​double​​​​price)​​​​​​​​{​​​​​​​​double​​​​price1 = 0.85 * price;​​​​​​​​Console.WriteLine(​​​​"Favourable Price : "​​​​+ price1);​​​​​​​​return​​​​price1;​​​​​​​​}​​​​​​​​​​​​static​​​​void​​​​Main(​​​​string​​​​[] args)​​​​​​​​{​​​​​​​​Price price = ​​​​new​​​​Price();​​​​​​​​//绑定Ordinary方法​​​​​​​​MyDelegate myDelegate = ​​​​new​​​​MyDelegate(price.Ordinary);​​​​​​​​//绑定Favourable方法​​​​​​​​myDelegate += ​​​​new​​​​MyDelegate(price.Favourable);​​​​​​​​//调用委托​​​​​​​​Console.WriteLine(​​​​"Current Price : "​​​​+ myDelegate(100));​​​​​​​​Console.ReadKey();​​​​​​​​}​​​​​​​​}​


输出

C# 委托、事件,lamda表达式_处理方法_02


1.2 委托的协变与逆变

前面已经说过,委托是强类型的方法指针,但是在面对具有继承关系类型的参数、或者返回值时,委托是如何处理的呢。

协变(返回值类型具有继承关系的方法)


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

​public​​​​class​​​​Worker​​​​​​​​{.......}​​​​​​​​public​​​​class​​​​Manager:Worker​​​​​​​​{.......}​​​​​​​​​​​​class​​​​Program​​​​​​​​{​​​​​​​​public​​​​delegate​​​​Worker GetWorkerHandler(​​​​int​​​​id);​​​​​​​​//在 Framework2.0 以上,委托 GetWorkerHandler 可绑定 GetWorker 与 GetManager 两个方法 ​​​​​​​​public​​​​static​​​​Worker GetWorker(​​​​int​​​​id)​​​​​​​​{​​​​​​​​Worker worker = ​​​​new​​​​Worker();​​​​​​​​return​​​​worker;​​​​​​​​}​​​​​​​​​​​​public​​​​static​​​​Manager GetManager(​​​​int​​​​id)​​​​​​​​{​​​​​​​​Manager manager = ​​​​new​​​​Manager();​​​​​​​​return​​​​manager;​​​​​​​​}​​​​​​​​​​​​static​​​​void​​​​Main(​​​​string​​​​[] args)​​​​​​​​{​​​​​​​​GetWorkerHandler workerHandler = ​​​​new​​​​GetWorkerHandler(GetWorker);​​​​​​​​Worker worker=workerHandler(1);​​​​​​​​GetWorkerHandler managerHandler = ​​​​new​​​​GetWorkerHandler(GetManager);​​​​​​​​Manager manager = managerHandler(2) ​​​​as​​​​Manager;​​​​​​​​Console.ReadKey();​​​​​​​​}​​​​​​​​}​


委托 GetWorkerHandler 可以绑定 GetWorker 与 GetManager 两个方法


逆变

委托逆变,是指委托方法的参数同样可以接收 “继承” 这个传统规则。像下面的例子,以 object 为参数的委托,可以接受任何 object 子类的对象作为参数。最后可以在处理方法中使用 is 对输入数据的类型进行判断,分别处理对不同的类型的对象。


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

​class​​​​Program​​​​​​​​{​​​​​​​​public​​​​delegate​​​​void​​​​Handler(​​​​object​​​​obj);​​​​​​​​​​​​public​​​​static​​​​void​​​​GetMessage(​​​​object​​​​message)​​​​​​​​{​​​​​​​​if​​​​(message ​​​​is​​​​string​​​​)​​​​​​​​Console.WriteLine(​​​​"His name is : "​​​​+ message.ToString());​​​​​​​​if​​​​(message ​​​​is​​​​int​​​​)​​​​​​​​Console.WriteLine(​​​​"His age is : "​​​​+ message.ToString());​​​​​​​​}​​​​​​​​​​​​static​​​​void​​​​Main(​​​​string​​​​[] args)​​​​​​​​{​​​​​​​​Handler handler = ​​​​new​​​​Handler(GetMessage);​​​​​​​​handler(29);​​​​​​​​Console.ReadKey();​​​​​​​​}​​​​​​​​}​



注意委托与其绑定方法的参数必须一至,即当 Handler 所输入的参数为 object 类型,其绑定方法 GetMessage 的参数也必须为 object 。否则,即使绑定方法的参数为 object 的子类,系统也无法辨认。


大家可能注意到了,这个委托方法GetMessage的实现不是那么优雅,于是泛型委托应运而生。


class Program { public delegate void Handler<T>(T obj); public static void GetWorkerWages(Worker worker) { Console.WriteLine("Worker's total wages is " + worker.Wages); } public static void GetManagerWages(Manager manager) { Console.WriteLine("Manager's total wages is "+manager.Wages); } static void Main(string[] args) { Handler<Worker> workerHander = new Handler<Worker>(GetWorkerWages); Worker worker = new Worker(); worker.Wages = 3000; workerHander(worker); Handler<Manager> managerHandler = new Handler<Manager>(GetManagerWages); Manager manager = new Manager(); manager.Wages = 4500; managerHandler(manager); Console.ReadKey(); } }


2. event事件的由来

事件是特殊的委托,他为委托提供了封装性,一方面允许从类的外部增加,删除绑定方法,另一方面又不允许从类的外部来触发委托所绑定了方法。



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55

​public​​​​delegate​​​​double​​​​PriceHandler();​​​​​​​​​​​​public​​​​class​​​​PriceManager​​​​​​​​{​​​​​​​​public​​​​PriceHandler GetPriceHandler;​​​​​​​​​​​​//委托处理,当价格高于100元按8.8折计算,其他按原价计算​​​​​​​​public​​​​double​​​​GetPrice()​​​​​​​​{​​​​​​​​if​​​​(GetPriceHandler.GetInvocationList().Count() > 0)​​​​​​​​{​​​​​​​​if​​​​(GetPriceHandler() > 100)​​​​​​​​return​​​​GetPriceHandler()*0.88;​​​​​​​​else​​​​​​​​return​​​​GetPriceHandler();​​​​​​​​}​​​​​​​​return​​​​-1;​​​​​​​​}​​​​​​​​}​​​​​​​​​​​​class​​​​Program​​​​​​​​{​​​​​​​​static​​​​void​​​​Main(​​​​string​​​​[] args)​​​​​​​​{​​​​​​​​PriceManager priceManager = ​​​​new​​​​PriceManager();​​​​​​​​​​​​//调用priceManager的GetPrice方法获取价格​​​​​​​​//直接调用委托的Invoke获取价格,两者进行比较​​​​​​​​priceManager.GetPriceHandler = ​​​​new​​​​PriceHandler(ComputerPrice);​​​​​​​​Console.WriteLine(​​​​string​​​​.Format(​​​​"GetPrice\n Computer's price is {0}!"​​​​,​​​​​​​​priceManager.GetPrice()));​​​​​​​​Console.WriteLine(​​​​string​​​​.Format(​​​​"Invoke\n Computer's price is {0}!"​​​​,​​​​​​​​priceManager.GetPriceHandler.Invoke()));​​​​​​​​​​​​Console.WriteLine();​​​​​​​​​​​​priceManager.GetPriceHandler = ​​​​new​​​​PriceHandler(BookPrice);​​​​​​​​Console.WriteLine(​​​​string​​​​.Format(​​​​"GetPrice\n Book's price is {0}!"​​​​,​​​​​​​​priceManager.GetPrice()));​​​​​​​​Console.WriteLine(​​​​string​​​​.Format(​​​​"Invoke\n Book's price is {0}!"​​​​,​​​​​​​​priceManager.GetPriceHandler.Invoke()));​​​​​​​​​​​​Console.ReadKey();​​​​​​​​}​​​​​​​​//书本价格为98元​​​​​​​​public​​​​static​​​​double​​​​BookPrice()​​​​​​​​{​​​​​​​​return​​​​98.0;​​​​​​​​}​​​​​​​​//计算机价格为8800元​​​​​​​​public​​​​static​​​​double​​​​ComputerPrice()​​​​​​​​{​​​​​​​​return​​​​8800.0;​​​​​​​​}​​​​​​​​}​


以上代码实现了对于100元以上商品的的88折处理。一方面为了给GetPriceHandler绑定方法就必须将委托声明为public,但是一旦声明为public

就可以在类外部直接通过Invoke来调用该委托所绑定的方法,而产生我们不需要的结果。

C# 委托、事件,lamda表达式_操作符_03


当然我们可以将GetPriceHandler声明为private并且通过public 的addHandler,removeHandler来消除委托public的副作用,但是C#提供了更加优雅的方法:

那就是event关键字。


事件(event)可被视作为一种特别的委托,它为委托对象隐式地建立起add_XXX、remove_XXX 两个方法,用作注册与注销事件的处理方法。而且事件对应的变量成员将会被视为 private 变量,外界无法超越事件所在对象直接访问它们,这使事件具备良好的封装性,而且免除了add_XXX、remove_XXX等繁琐的代码。


1 2 3 4 5

​public​​​​class​​​​EventTest​​​​​​​​{​​​​​​​​public​​​​delegate​​​​void​​​​MyDelegate();​​​​​​​​public​​​​event​​​​MyDelegate MyEvent;​​​​​​​​}​



观察事件的编译过程可知,在编译的时候,系统为 MyEvent 事件自动建立add_MyEvent、remove_MyEvent 方法。

C# 委托、事件,lamda表达式_操作符_04


事件能通过+=和-=两个方式注册或者注销对其处理的方法,使用+=与-=操作符的时候,系统会自动调用对应的 add_XXX、remove_XXX 进行处理。

值得留意,在PersonManager类的Execute方法中,如果 MyEvent 绑定的处理方法不为空,即可使用MyEvent(string)引发事件。但如果在外界的 main 方法中直接使用 personManager.MyEvent (string) 来引发事件,系统将引发错误报告。这正是因为事件具备了良好的封装性,使外界不能超越事件所在的对象访问其变量成员。


注意在事件所处的对象之外,事件只能出现在+=,-=的左方。


public delegate void MyDelegate(string name);


     public class PersonManager

     {

         public event MyDelegate MyEvent;


         //执行事件

         public void Execute(string name)

         {

             if (MyEvent != null)

                 MyEvent(name);

         }

     }


     class Program

     {

         static void Main(string[] args)

         {

             PersonManager personManager = new PersonManager();

             //绑定事件处理方法

             personManager.MyEvent += new MyDelegate(GetName);

             personManager.Execute("Leslie");

             Console.ReadKey();

         }


         public static void GetName(string name)

         {

             Console.WriteLine("My name is " + name);

         }

     }


在绑定事件处理方法的时候,事件出现在+=、-= 操作符的左边,对应的委托对象出现在+=、-= 操作符的右边。对应以上例子,事件提供了更简单的绑定方式,只需要在+=、-= 操作符的右方写上方法名称,系统就能自动辩认。



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21

​public​​​​delegate​​​​void​​​​MyDelegate(​​​​string​​​​name);​​​​​​​​​​​​public​​​​class​​​​PersonManager​​​​​​​​{​​​​​​​​public​​​​event​​​​MyDelegate MyEvent;​​​​​​​​.........​​​​​​​​}​​​​​​​​​​​​class​​​​Program​​​​​​​​{​​​​​​​​static​​​​void​​​​Main(​​​​string​​​​[] args)​​​​​​​​{​​​​​​​​PersonManager personManager = ​​​​new​​​​PersonManager();​​​​​​​​//绑定事件处理方法​​​​​​​​personManager.MyEvent += GetName;​​​​​​​​.............​​​​​​​​}​​​​​​​​​​​​public​​​​static​​​​void​​​​GetName(​​​​string​​​​name)​​​​​​​​{.........}​​​​​​​​}​


如果觉得编写 GetName 方法过于麻烦,你还可以使用匿名方法绑定事件的处理。



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24

​public​​​​delegate​​​​void​​​​MyDelegate(​​​​string​​​​name);​​​​​​​​​​​​public​​​​class​​​​PersonManager​​​​​​​​{​​​​​​​​public​​​​event​​​​MyDelegate MyEvent;​​​​​​​​​​​​//执行事件​​​​​​​​public​​​​void​​​​Execute(​​​​string​​​​name)​​​​​​​​{​​​​​​​​if​​​​(MyEvent != ​​​​null​​​​)​​​​​​​​MyEvent(name);​​​​​​​​}​​​​​​​​​​​​static​​​​void​​​​Main(​​​​string​​​​[] args)​​​​​​​​{​​​​​​​​PersonManager personManager = ​​​​new​​​​PersonManager();​​​​​​​​//使用匿名方法绑定事件的处理​​​​​​​​personManager.MyEvent += ​​​​delegate​​​​(​​​​string​​​​name){​​​​​​​​Console.WriteLine(​​​​"My name is "​​​​+name);​​​​​​​​};​​​​​​​​personManager.Execute(​​​​"Leslie"​​​​);​​​​​​​​Console.ReadKey();​​​​​​​​}​​​​​​​​}​


1



3. lambda表达式


在Framework 2.0 以前,声明委托的唯一方法是通过方法命名,从Framework 2.0 起,系统开始支持匿名方法。

通过匿名方法,可以直接把一段代码绑定给事件,因此减少了实例化委托所需的编码系统开销。

而在 Framework 3.0 开始,Lambda 表达式开始逐渐取代了匿名方法,作为编写内联代码的首选方式。总体来说,Lambda 表达式的作用是为了使用更简单的方式来编写匿名方法,彻底简化委托的使用方式。

使用匿名方法


1 2 3 4 5 6 7

​static​​​​void​​​​Main(​​​​string​​​​[] args)​​​​​​​​{​​​​​​​​Button btn = ​​​​new​​​​Button();​​​​​​​​btn.Click+=​​​​delegate​​​​(​​​​object​​​​obj,EventArgs e){​​​​​​​​MessageBox.Show(​​​​"Hello World !"​​​​);​​​​​​​​};​​​​​​​​}​


使用lambda表达式


1 2 3 4 5 6 7

​static​​​​void​​​​Main(​​​​string​​​​[] args)​​​​​​​​{​​​​​​​​Button btn = ​​​​new​​​​Button();​​​​​​​​btn.Click+=(​​​​object​​​​obj,EventArgs e)=>{​​​​​​​​MessageBox.Show(​​​​"Hello World !"​​​​);​​​​​​​​};​​​​​​​​}​



3.1常用泛型委托

public delegate bool Predicate<T>(T obj)

它是一个返回bool的泛型委托,能接受一个任意类型的对象作为参数。


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43

​class​​​​Program​​​​​​​​{​​​​​​​​static​​​​void​​​​Main(​​​​string​​​​[] args)​​​​​​​​{​​​​​​​​List<Person> list = GetList();​​​​​​​​//绑定查询条件​​​​​​​​Predicate<Person> predicate = ​​​​new​​​​Predicate<Person>(Match);​​​​​​​​List<Person> result = list.FindAll(predicate);​​​​​​​​Console.WriteLine(“Person count ​​​​is​​​​: ” + result.Count);​​​​​​​​Console.ReadKey();​​​​​​​​}​​​​​​​​//模拟源数据​​​​​​​​static​​​​List<Person> GetList()​​​​​​​​{​​​​​​​​var​​​​personList = ​​​​new​​​​List<Person>();​​​​​​​​var​​​​person1 = ​​​​new​​​​Person(1,​​​​"Leslie"​​​​,29);​​​​​​​​personList.Add(person1);​​​​​​​​........​​​​​​​​return​​​​personList;​​​​​​​​}​​​​​​​​//查询条件​​​​​​​​static​​​​bool​​​​Match(Person person)​​​​​​​​{​​​​​​​​return​​​​person.Age <= 30;​​​​​​​​}​​​​​​​​}​​​​​​​​​​​​public​​​​class​​​​Person​​​​​​​​{​​​​​​​​public​​​​Person(​​​​int​​​​id, ​​​​string​​​​name, ​​​​int​​​​age)​​​​​​​​{​​​​​​​​ID = id;​​​​​​​​Name = name;​​​​​​​​Age = age;​​​​​​​​}​​​​​​​​​​​​public​​​​int​​​​ID​​​​​​​​{ ​​​​get​​​​; ​​​​set​​​​; }​​​​​​​​public​​​​string​​​​Name​​​​​​​​{ ​​​​get​​​​; ​​​​set​​​​; }​​​​​​​​public​​​​int​​​​Age​​​​​​​​{ ​​​​get​​​​; ​​​​set​​​​; }​​​​​​​​}​


1



Action<T> 的使用方式与 Predicate<T> 相似,不同之处在于 Predicate<T> 返回值为 bool ,  Action<T> 的返回值为 void。

Action 支持0~16个参数,可以按需求任意使用。

public delegate void Action()

public delegate void Action<T1>(T1 obj1)

public delegate void Action<T1,T2> (T1 obj1, T2 obj2)

public delegate void Action<T1,T2,T3> (T1 obj1, T2 obj2,T3 obj3)

............

public delegate void Action<T1,T2,T3,......,T16> (T1 obj1, T2 obj2,T3 obj3,......,T16 obj16)


1 2 3 4 5 6 7 8 9 10 11

​static​​​​void​​​​Main(​​​​string​​​​[] args)​​​​​​​​{​​​​​​​​Action<​​​​string​​​​> action=ShowMessage;​​​​​​​​action(​​​​"Hello World"​​​​);​​​​​​​​Console.ReadKey();​​​​​​​​}​​​​​​​​​​​​static​​​​void​​​​ShowMessage(​​​​string​​​​message)​​​​​​​​{​​​​​​​​MessageBox.Show(message);​​​​​​​​}​


1



委托 Func 与 Action 相似,同样支持 0~16 个参数,不同之处在于Func 必须具有返回值

public delegate TResult Func<TResult>()

public delegate TResult Func<T1,TResult>(T1 obj1)

public delegate TResult Func<T1,T2,TResult>(T1 obj1,T2 obj2)

public delegate TResult Func<T1,T2,T3,TResult>(T1 obj1,T2 obj2,T3 obj3)

............

public delegate TResult Func<T1,T2,T3,......,T16,TResult>(T1 obj1,T2 obj2,T3 obj3,......,T16 obj16)


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

​static​​​​void​​​​Main(​​​​string​​​​[] args)​​​​​​​​{​​​​​​​​Func<​​​​double​​​​, ​​​​bool​​​​, ​​​​double​​​​> func = Account;​​​​​​​​double​​​​result=func(1000, ​​​​true​​​​);​​​​​​​​Console.WriteLine(​​​​"Result is : "​​​​+result);​​​​​​​​Console.ReadKey();​​​​​​​​}​​​​​​​​​​​​static​​​​double​​​​Account(​​​​double​​​​a,​​​​bool​​​​condition)​​​​​​​​{​​​​​​​​if​​​​(condition)​​​​​​​​return​​​​a * 1.5;​​​​​​​​else​​​​​​​​return​​​​a * 2;​​​​​​​​}​




3.2 lambda表达式

Lambda 的表达式的编写格式如下:

x=> x * 1.5

当中 “ => ” 是 Lambda 表达式的操作符,在左边用作定义一个参数列表,右边可以操作这些参数。

例子一, 先把 int x 设置 1000,通过 Action 把表达式定义为 x=x+500 ,最后通过 Invoke 激发委托。

static void Main(string[] args)

         {

             int x = 1000;

             Action action = () => x = x + 500;

             action.Invoke();


             Console.WriteLine("Result is : " + x);

             Console.ReadKey();

         }


例子二,通过 Action<int> 把表达式定义 x=x+500, 到最后输入参数1000,得到的结果与例子一相同。

注意,此处Lambda表达式定义的操作使用 { } 括弧包括在一起,里面可以包含一系列的操作。

static void Main(string[] args)

         {

             Action<int> action = (x) =>

             {

                 x = x + 500;

                 Console.WriteLine("Result is : " + x);

             };

             action.Invoke(1000);

             Console.ReadKey();

         }


失败是什么?没有什么,只是更走近成功一步;成功是什么?就是走过了所有通向失败的路,只剩下一条路,那就是成功的路。