(11)委托和Lamda表达式

**委托(delegate):一个表示方法的数据类型。间接派生于System.Delegate

委托是一个引用类型,但不必用new来实例化它。直接传递名称,而不是现实实例化。这是c#2.0开始支持的一个新语法,成为委托推断(delegate inference)

[csharp]  view plain copy
  1. namespace delegateEx  
  2. {  
  3.     //委托声明  
  4.     public delegate bool ComparisonHandler(int first,int second);  
  5.   
  6.     public static class DelegateSample   
  7.     {   //  
  8.         public static void BubbleSort(int[] items, ComparisonHandler comparisonMethod)  
  9.         {  
  10.             int i;  
  11.             int j;  
  12.             int temp;  
  13.             if (items == null)  
  14.             {  
  15.                 return;  
  16.             }  
  17.             if (comparisonMethod == null)  
  18.             {  
  19.                 throw new ArgumentNullException("comparisonMethod");  
  20.             }  
  21.   
  22.             for (i = items.Length - 1; i >= 0; i--)  
  23.             {  
  24.                 for (j = 1; j <= i; j++)  
  25.                 {  
  26.                     //用委托实例  
  27.                     if (comparisonMethod(items[j - 1], items[j]))  
  28.                     {  
  29.                         temp = items[j - 1];  
  30.                         items[j - 1] = items[j];  
  31.                         items[j] = temp;  
  32.                     }  
  33.                 }  
  34.             }  
  35.         }  
  36.         //匹配委托的参数GreaterThan(int first, int second)  
  37.         public static bool GreaterThan(int first, int second)  
  38.         {  
  39.             return first > second;  
  40.         }  
  41.     }  
  42.     class Program  
  43.     {  
  44.         static void Main(string[] args)  
  45.         {  
  46.             int[] items = new int[100];  
  47.             Random random = new Random();  
  48.             for (int i = 0; i < items.Length; i++)  
  49.             {  
  50.                 items[i] = random.Next(1,100);  
  51.             }  
  52.             //将委托实例作为参数传递  
  53.             DelegateSample.BubbleSort(items, DelegateSample.GreaterThan);  
  54.   
  55.             for (int i = 0; i < items.Length; i++)  
  56.             {  
  57.                 Console.Write(" {0}",items[i]);  
  58.             }  
  59.             Console.ReadKey();  
  60.         }  
  61.     }  
  62. }<strong>  
  63. </strong>  
**匿名方法:就是没有实际方法声明委托实例,或者说,他们的定义是直接内嵌在代码中的。

[csharp]  view plain copy
  1. static void Main(string[] args)  
  2. {  
  3.     int[] items = new int[5];  
  4.     Random random = new Random();  
  5.     ComparisonHandler comparisonMethod;  
  6.   
  7.     for (int i = 0; i < items.Length; i++)  
  8.     {  
  9.         items[i] = random.Next(1, 100);  
  10.     }  
  11.   //委托的定义直接内嵌在代码中。  
  12.     comparisonMethod = delegate(int first, int second)  
  13.     {  
  14.         return first < second;  
  15.     };  
  16.     BubbleSort(items,comparisonMethod);  
  17.   
  18.     for (int i = 0; i < items.Length; i++)  
  19.     {  
  20.         Console.Write(" {0}", items[i]);  
  21.     }  
  22.     Console.ReadKey();  
  23. }  
或者使用更直接的方法:

[csharp]  view plain copy
  1. BubbleSort(items,  
  2.     delegate(int first, int second)  
  3. {  
  4.     return first < second;  
  5. });  

注意,在任何情况下,参数和返回值类型必须兼容于委托的数据类型。

*匿名方法是允许省略参数列表的,但是返回值类型需要与委托一致。

**系统定义的委托:

System.Func 在.NET 3.5中代表有返回类型的委托

System.Action代表无返回类型的委托。

不能将一个委托类型赋给另一个委托类型的变量,即使类型参数匹配。

*为委托使用可变性[还没理解]

Action<object> broadAction=delegate(object data)

{

Console.WriteLine(data);

}

Action<string> narrowAction=broadAction;


Func<string>narrowFunction=delegate()

{

return Console.WriteLine();

};

Func<object> broadFunction=narrowAction;


Func<object ,string >func1=

degate(object data)

{

return data.ToString();

};

Func<string,object>func2=fun1;



**Lamda表达式 (关键字=>) :分为Lamda表达式和Lamda语句

[csharp]  view plain copy
  1. <strong>      </strong>      BubbleSort(items,  
  2.                 delegate(int first, int second)  
  3.             {  
  4.                 return first < second;  
  5.             });  
与上述等价的 Lamda语句(用于)

[csharp]  view plain copy
  1. BubbleSort(items,  
  2.     (int first, int second)=>  
  3.     {  
  4.         return first < second;  
  5.     }  
  6. );  
*省略参数类型:通常,只要编译器能推断出参数类型,或者能将参数类型隐式转换成期望的数据类型,语句Lamda就不需要参数类型。如果要制定类型,那么制定的类型必须和委托类型完全匹配。只要Lamda语句包含了一个类型,则所有的类型都要加上。

[csharp]  view plain copy
  1. BubbleSort(items,  
  2.     (first,second)=>  
  3.     {  
  4.         return first < second;  
  5.     }  
  6. );  
*c#要求用一对圆括号来封闭Lamda表达式的参数类表,不管是否指定了这些参数的数据类型。圆括号的另外一个规则是,当编译器能推断出数据类型,而且只有一个输入参数的时候,语句Lamda可以不带圆括号。

Func<string> getUserInput=

()=>

string input;;

do

{     input=Console.ReadLine();}

while(input.Trim()==0);

return input;

}

*Lamda表达式(满足……条件)

[csharp]  view plain copy
  1. BubbleSort(items,  
  2.     (int first, int second)=> first < second );  

**Lamda表达式本身没有类型

所以   .    运算符不会被编译,调用Object的方法也不行。

不能出现在is的左侧

Lamda表达式一旦被赋值或者转型,就会有Lamda表达式的类型这种非正式的说法

不能赋值给隐式类型的变量

如果目的在Lamda表达式的外部,c#就不允许在匿名函数内部使用跳转语句(break,continue,goto)

*外部变量:在Lamda表达式(包括参数)的外部声明,但是Lamda表达式的内部捕捉(访问)的局部变量称为外部变量。this也是一个外部变量。

int comparisonCount=0;

...

BubbleSort(item,

(int first ,int second)=>

{        

                 comparisonCount++;

return first<second;

}

);

Console.WriteLine(comparisonCount);

**表达式树[不理解]

“解释”是c#引入表达式树(expression trees)这一概念的重要动机。如果一种Lamda表达式代表的是与表达式有关的数据,而不是编译好的代码,这中Lamda表达式就是表达式树。由于表达式树代表的是数据而非编译好的代码,所以可以把数据转换成一种替代格式。例如,转换成SQL代码。

persons.Where(person=>person.Name.ToUpper()=="INIGO MONTOYA")

select *from Person where upper(Name)='INIGO MONTOYA'


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值