委託的實現匿名函數和朗姆達表達式

**委託(delegate):一個表示方法的數據類型。間接派生於System.Delegateexpress

委託是一個引用類型,但沒必要用new來實例化它。直接傳遞名稱,而不是現實實例化。這是c#2.0開始支持的一個新語法,成爲委託推斷(delegate inference)c#

 

 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 }

 

**匿名方法:就是沒有實際方法聲明委託實例,或者說,他們的定義是直接內嵌在代碼中的。dom

 

 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 } 

 

或者使用更直接的方法:函數

1 BubbleSort(items,  
2     delegate(int first, int second)  
3 {  
4     return first < second;  
5 });  

注意,在任何狀況下,參數和返回值類型必須兼容於委託的數據類型。this

*匿名方法是容許省略參數列表的,可是返回值類型須要與委託一致。spa

**系統定義的委託:.net

System.Func 在.NET 3.5中表明有返回類型的委託code

System.Action表明無返回類型的委託。blog

不能將一個委託類型賦給另外一個委託類型的變量,即便類型參數匹配。ip

*爲委託使用可變性[還沒理解]

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 BubbleSort(items,  
2                 delegate(int first, int second)  
3             {  
4                 return first < second;  
5             });  

與上述等價的Lamda語句(用於)

1 BubbleSort(items,  
2     (int first, int second)=>  
3     {  
4         return first < second;  
5     }  
6 ); 

 

 

*省略參數類型:一般,只要編譯器能推斷出參數類型,或者能將參數類型隱式轉換成指望的數據類型,語句Lamda就不須要參數類型。若是要制定類型,那麼制定的類型必須和委託類型徹底匹配。只要Lamda語句包含了一個類型,則全部的類型都要加上。

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表達式(知足……條件)


 

  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'

相關文章
相關標籤/搜索