Reference
Orcas中C#語言的新特性:自動屬性,對象初始化器,和集合初始化器
新Orcas語言特性:擴充方法
1. 自動屬性: public class Person {
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
}
當Orcas版中的C#編譯器遇上象上面這樣的空的get/set屬性的話,它會自動為你在類中產生一個私人成員變數,對這個變數實現一個公開的getter 和setter
2. 對象初始化器:
Person person = new Person { FirstName = "Scott" , LastName = "Guthrie" , Age = 32 } ;
就不用Person person = new Person(); person.FirstName="scott";
當然也允許嵌套:
Person person = new Person {
FirstName = "Scott" ,
LastName = "Guthrie"
Age = 32 ,
Address = new Address {
Street = "One Microsoft Way" ,
City = "Redmond" ,
State = "WA" ,
Zip = 98052
}
} ;
3 集合初始化器
List<Person> people = new List<Person> {
new Person { FirstName = "Scott" , LastName = "Guthrie" , Age = 32 },
new Person { FirstName = "Bill" , LastName = "Gates" , Age = 50 },
new Person { FirstName = "Susanne" , LastName = "Guthrie" , Age = 32 }
} ;
當編譯器遇上上面這樣的句法時,它會自動為我們產生集合插入編碼。
即 List<Persion> people = new List<Person>(); Person.Add(new Person{...}); Person.Add(new Person{...});
4. 擴充方法
例如,驗證一個字串是否為合法
一般寫法,定義一個類,實現靜態方法IsValid(string): string email = Request.QueryString[ "email" ] ;
if ( EmailValidator.IsValid(email) ) {
}
擴充方法允許:
string email = Request.QueryString[ "email" ] ;
if ( email.IsValidEmailAddress() ) {
}
擴充方法如何?:
public static class ScottGuExtensions
{
public static bool IsValidEmailAddress( this string s)
{
Regex regex = new Regex( @"^[/w-/.]+@([/w-]+/.)+[/w-]{2,4}$" ) ;
return regex.IsMatch(s) ;
}
}
注意,靜態方法的string的參數變數前有個“this”關鍵詞,這告訴編譯器,這個特定的擴充方法應該添加到類型為“string”的對象中去。
使用時,要用“using”語句來引入含有該擴充方法的實現的命名空間
下面完全轉載過來,寫的很明了 擴充方法使用情境續...
利用擴充方法這個新特性來給個別類型添加方法給開發人員開闢了許多有用的擴充性使用情境。但使得擴充方法非常強有力的是,它們不僅能夠應用到個別類型上,也能應用到.NET架構中任何基類或介面上。這允許開發人員建立種種可用於整個.NET架構的豐富的可組合的架構層擴充。
譬如,考慮這樣一個情境,我想要一個既容易,描述性又強的方式來檢查一個對象是否已經包含在一個對象集合或數組裡。我可以定義一個簡單的.In(集合)擴充方法,我想把它添加到.NET架構中的所有對象上,我可以在C#裡這麼來實現這個“In()”擴充方法:
注意上面我是如何聲明擴充方法的第一個參數的:“this object o”。這表明,這個擴充方法應該適用於繼承於基類System.Object的所有類型,這意味著我可以在.NET中的每個對象上使用它。
上面這個“In”方法的實現允許我檢查一個指定的對象是否包含在作為方法參數傳入的一個IEnumerable序列中。因為所有的.NET集合和數組都實現了IEnumerable介面,現在我擁有了一個有用的,描述性強的方法來檢查一個任意的對象是否屬於任何.NET集合或數組。
然後我就可以使用這個“In()”方法來看一個特定的字串是否在一個字串數組中:
我也可以用它來檢查一個特定的ASP.NET控制項是否在一個容器控制項集合裡:
我甚至可以將其用在象整數這樣的純量資料型別上:
注意上面,你甚至可以在象整數值42這樣的基礎資料型別 (Elementary Data Type)值上使用擴充方法。因為CLR支援數實值型別的自動boxing/unboxing,擴充方法可以直接使用在數值和其他純量資料型別上。
你大概可以開始從上面的例子中看出,擴充方法可以促成一些非常豐富和描述性強的擴充性使用情境。當使用於.NET中常見的基類和介面上時,他們可以促成一些非常好的特定於某個領域(domain specific)的架構和組合使用情境。 內建的System.Linq擴充方法
一個在Orcas時段隨.NET發布的內建的擴充方法庫是一套允許開發人員對任何資料進行查詢的非常強有力的查詢擴充方法。這些擴充方法實現位於新的 System.Linq 命名空間之下,定義了標準的查詢操作符擴充方法,可以為.NET開發人員用來輕鬆地查詢XML,關聯式資料庫,.NET 對象, 和任何其他資料結構類型。
下面是使用這些查詢擴充方法的擴充性模型的幾個好處:
1) 它允許一個可用於所有資料類型(資料庫,XML檔案,記憶體中的對象,以及web-services等)的共同的查詢編程模型和文法。
2) 它是可以組合的,允許開發人員輕鬆地往查詢文法中添加新的方法/操作符。譬如,我們可以將我們自訂的“In()”方法與為LINQ所定義的標準的“Where()”方法作為一個單獨查詢的一部分一起使用。我們自訂的In()方法看上去就跟由System.Linq命名空間提供的標準方法一樣。
3) 它是可擴充的,允許與任何資料提供器類型一起使用。譬如,任何一個象NHibernate或LLBLGen這樣現有的ORM引擎可以實現LINQ的標準查詢操作符來允許對他們現有的ORM實現和映射引擎實現LINQ查詢。這允許開發人員學會一個查詢資料的共同方式,然後對種類繁多的豐富資料存放區實現使用同樣的技能。
我將在下幾個星期裡對LINQ作更多的示範,但想留給你幾個例子,這些例子展示了如何對不同類型的資料使用幾個內建的LINQ查詢擴充方法: 使用情境一:對記憶體中的.NET對象使用LINQ擴充方法
假定我們象這樣定義了代表“Person”的類:
然後建立和填充一個“people”集合,象這樣:
然後我可以使用由System.Linq提供的標準的“Where()”擴充方法來擷取這個集合中FirstName的首字元是"S"的那些“Person”對象,象這樣:
Where()就是擴充方法。以函數為參數。
上面這個新的 p => 文法是“Lambda運算式”的一個例子,是對C# 2.0匿名方法支援的更簡明的發展,允許我們通過一個實參來輕鬆地表達查詢過濾(在這個情形下,我們表示我們只想要返回一串firstname屬性的首字元是“S”字母的Person對象) 。上面這個查詢然後就會返回包含2個對象的序列,Scott 和 Susanne。
我也可以利用由System.Linq提供的新的“Average” 和“Max”擴充方法編寫代碼來決定我的集合裡的人的平均年齡,以及年齡最大的人,象這樣:
使用情境二:對XML檔案使用LINQ擴充方法
你手工在記憶體裡建立一個硬寫(hard-coded)的資料集合大概是很少見的。更有可能的是,你會從一個XM檔案,資料庫,或web服務裡擷取資料。
假定我們在硬碟上有一個XML檔案,包含下面這樣的資料:
很明顯地,我可以使用現有的 System.Xml APIs 來裝載這個XML檔案進一個DOM,然後訪問它,或者使用一個層次較低的XmlReader API ,自己對之手工分析。或者,在 Orcas中,我現在也可以使用支援標準的LINQ擴充方法的System.Xml.Linq 實現(即 XLINQ),更優雅地分析和處理XML。
下面的代碼例子展示了如何使用LINQ來擷取所有包含一個子節點的值的首字母為“S”的<person> XML元素:
注意,它使用了跟記憶體中對象例子中一模一樣的 Where() 擴充方法。現在它返回一個“XElement”元素序列,XElemen是沒有類型的XML節點元素。或者我也可以重寫查詢運算式,通過LINQ的 Select() 擴充方法來構造資料形狀,其實就是映射,將過濾得到的XElement元素序列映射為對象序列:
上面的代碼會做需要開啟,分析,和過濾XML,然後返回一個強型別的Person對象序列所有的工作。
我也可以和前面一樣使用同樣的Average() 和 Max() LINQ擴充方法來計算XML檔案中<person>元素的平均年齡,以及最大年齡,象這樣:
我不用手工分析XML檔案,XLINQ 不僅可以為我處理分析,它在估算LINQ運算式時,也可以使用低層的XMLReader,而不是使用DOM來分析檔案。這意味著它是迅速之極,而且不分配很多記憶體。 使用情境三:對資料庫使用LINQ擴充方法
假定我們擁有一個SQL資料庫,內含一個叫“People”的表,具有下列資料定義:
我可以使用Visual Studio中新的LINQ到SQL的所見即所得 (WYSIWYG)(WYSIWYG) ORM設計器,快速地建立一個映射到資料庫的“Person”類:
然後我可以使用我先前用於對象和XML檔案同樣的LINQ Where() 擴充方法,從資料庫中擷取firstname的首字元為“S”的強型別“Person”對象序列:
注意,查詢句法與對象和XML情境中的一模一樣。
然後我也可以使用與前面一樣的 LINQ Average() 和Max() 擴充方法來從資料庫裡擷取平均和最大值,象這樣:
要使上面代碼例子工作,你自己不需編寫任何SQL代碼。Orcas中提供的LINQ to SQL對象關係映射器會處理擷取,跟蹤,和更新映射到你的資料庫資料定義和預存程序的對象。你只要使用任何LINQ擴充方法對結果進行過濾和構形即可,LINQ to SQL會執行擷取資料所需的SQL代碼(注意,上面的 Average和Max 擴充方法很明顯地不會從資料表中返回所有的資料行,它們會使用TSQL的彙總函式來計算資料庫中的值,然後只返回一個標量值)。
請觀看我一月份製作的一個錄影,示範了LINQ到SQL如何顯著地改進了Orcas中的資料生產力。錄影中,你也可以看到新的LINQ to SQL的所見即所得 (WYSIWYG)ORM設計器的實戰示範,以及對資料模型編寫LINQ代碼時代碼編輯器提供的完整的 intellisense。