本文例子大部分來自于(Apress pro linq)
為了使LINQ可以無縫的和C#語言整合在一起,微軟對C#3.0加入了些新功能,這裡主要介紹和LINQ相關的加強。
1、var關鍵字,集合初始化以及匿名類型
2、Lambda 表達式
3、部分(Partial )方法
4、擴充方法
5、表達式樹
1、var關鍵字,集合初始化以及匿名類型
var:
可以賦予局部變量推斷“類型”var 而不是顯式類型。var 關鍵字訓示編譯器根據初始化語句右側的表達式推斷變量的類型。推斷類型可以是内置類型、匿名類型、使用者定義類型、.NET Framework 類庫中定義的類型或任何表達式。var隻是表示由編譯器确定和配置設定最适當的類型。和javascript中的var的概念不同.例如:var i = 5;編譯完之後i就是一個整型,和int i=5;沒有任何差別.在很多情況下,var 是可選的,它隻是提供了文法上的便利。
請看如下例子:
var i = 5;//int
var j = 23.56;//double
var k = "C Sharp";//string
var x;//錯誤
var y = null;//錯誤
var z = { 1, 2, 3 };//錯誤
對象和集合初始值設定項:

Code
User user = new User();
user.Id = 1;
user.Name = “lfm";
user.Age = 22;
在VS2008中,編譯器會自動地生成合适的屬性setter代碼,使得原來幾行的屬性指派操作可以在一行完成。我們可以這樣簡化:像這樣,對象初始化器由一系列成員對象組成,其對象必須初始化,用逗号間隔,使用{}封閉。
User user = new User { Id = 1, Name = “lfm", Age = 22 };
又例如,我把二個人加到一個基于泛型的類型為User的List集合中:
List<User> user = new List<User>{
new User{Id=1,Name=“lfm",Age=22},
new User{Id=2,Name=“tmx",Age=25},
};
匿名類型:
匿名類型提供了一種友善的方法,可用來将一組隻讀屬性封裝到單個對象中,而無需首先顯式定義一個類型。類型名由編譯器生成,并且不能在源代碼級使用。這些屬性的類型由編譯器推斷。
匿名類型允許定義行内類型,無須顯式定義類型。在将匿名類型配置設定給變量時,必須使用 var 構造初始化該變量。
//屬性也不需要申明,這些屬性的類型由編譯器推斷
var p1 = new { Id = 1, Name = “lfm", Age = 22 };
var p2 = new { Id = 2, Name = “tmx", Age = 25 };
p1 = p2;//p1,p2結構相同,可以互相指派
在這裡編譯器會認為p1,p2相當于:
public class SomeType
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
備注(from msdn)
匿名類型是直接從對象派生的引用類型。盡管應用程式無法通路匿名類型,但編譯器仍會為其提供一個名稱。從公共語言運作庫的角度來看,匿名類型與任何其他引用類型沒有什麼不同。
如果兩個或更多個匿名類型以相同的順序具有相同數量和種類的屬性,則編譯器會将這些匿名類型視為相同的類型,并且它們共享編譯器生成的相同類型資訊。
匿名類型具有方法範圍。若要向方法邊界外部傳遞一個匿名類型或一個包含匿名類型的集合,必須首先将匿名類型強制轉換為對象。但是,這會使匿名類型的強類型化無效。如果必須存儲查詢結果或者必須将查詢結果傳遞到方法邊界外部,請考慮使用普通的命名結構或類而不是匿名類型。
在c#3.0中微軟加入了“Lambda 表達式”,“Lambda 表達式”的概念最早是數學家Alonzo Church在1936年提出的,早在LISP語言中就已經得到應用。這些表達式提供了簡短的文法來表達一個運算法則。在C#3.0中“Lambda 表達式”是一個匿名函數,它可以包含表達式和語句,并且可用于建立委托或表達式目錄樹類型。在我們詳細講解“Lambda 表達式”之前,我們先來了解一下“Lambda 表達式”出現的原因。
我們假設這樣一個場景,我們希望有這樣一個函數,對一個整型數組進行過濾,而過濾得條件在編寫函數時還不知道,直到使用這個函數的時候可以根據目前的情況編寫過濾條件函數,大家一看到這個場景可能馬上想到,可以使用委托阿。ok,代碼如下:
<a></a>
public class Common
{
public delegate bool IntFilter(int i);
public static int[] FilterArrayOfInts(int[] ints, IntFilter filter)
{
ArrayList aList = new ArrayList();
foreach (int i in ints)
{
if (filter(i))
{
aList.Add(i);
}
}
return ((int[])aList.ToArray(typeof(int)));
}
}
public class Application
public static bool IsOdd(int i)
return ((i & 1) == 1);
static void Main(string[] args)
int[] nums = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int[] oddNums = Common.FilterArrayOfInts(nums, Application.IsOdd);
foreach (int i in oddNums)
Console.WriteLine(i);
結果為:
1
3
5
7
9
看了這段代碼之後,大家可能會覺得這個實作可能不夠好,這裡的IsOdd函數可能隻用這麼一次,并且也太簡單了,不值得當成一個函數來用,于是我們想到了C#2.0的匿名委托,實作代碼如下:
int[] oddNums =
Common.FilterArrayOfInts(nums, delegate(int i) { return ((i & 1) == 1); });
恩,這段代碼似乎相當棒了,解決了我剛才說的所有問題,但是看起來好象不夠簡潔,也比較難懂些。我希望有一個更好的方式來解決這個問題。
我們先來看看“Lambda 表達式”的用法,所有 Lambda 表達式都使用 Lambda 運算符 =>,該運算符讀為“goes to”。該 Lambda 運算符的左邊是輸入參數(如果有),右邊包含表達式或語句塊。Lambda 表達式 x => x * x 讀作“x goes to x 乘x”其意義就是輸入x傳回x乘x。
Lambda 表達式傳回表達式的結果,并采用以下基本形式:
(input parameters) => {statement;}
多個參數時可以使用如下方式
(param1, param2, …paramN) => expr
更為複雜的方式可以如下表示
(param1, param2, …paramN) =>
statement1;
statement2;
…
statementN;
return(lambda_expression_return_type);
這裡大家需要知道的是“Lambda 表達式”其實就是一個匿名委托,可以使用“Lambda 表達式”的地方必須是可以使用委托的地方,Lambda 運算符 =>左邊的是輸入參數,Lambda 運算符 =>右邊的部分是執行後的輸出結果
比如
x => x.Length > 0
相當于
delegate(string x) { return x.Length > 0; }
大家了解了“Lambda 表達式”,我們就可以使用“Lambda 表達式”來完成剛才過濾資料的場景了。代碼如下:
int[] oddNums = Common.FilterArrayOfInts(nums, i => ((i & 1) == 1));
這段代碼比剛才匿名委托的方式易讀性要好很多了吧
本文轉自 你聽海是不是在笑 部落格園部落格,原文連結:http://www.cnblogs.com/nuaalfm/archive/2008/08/06/1262202.html ,如需轉載請自行聯系原作者