摘要:Orcas中C#語言的新特性:自動屬性實作,物件初始化器,和集合初始化器
【原文位址】New C# 「Orcas」 Language Features: Automatic Properties, Object Initializers, and Collection Initializers
【原文發表日期】 Thursday, March 08, 2007 11:01 PM
上個星期,我們發佈了我們的Visual Studio和.NET框架Orcas版三月份的CTP,這是個誰都可以下的免費下載,同時提供VPC鏡像(允許你在一個虛擬機裡運行它)以及單獨的安裝文件(註:如果你在運行Vista的話,你要確認你只使用VPC版本)。你可以在這裡下載。
幾個星期前,我曾在部落格上討論過Orcas中針對ASP.NET開發人員的一些重大的改進。如果你還沒有讀過這個文章的話,我強烈建議你在這裡讀一下。我認為你會非常喜歡該文章討論的新特性的。
除了那些框架和工具類的精彩新特性外,我認為開發人員(包括所有的.NET應用型別的開發人員)會非常喜愛Orcas的一件事情是,VB和C#將包含一些新語言特性和改進。這些語言改動將以既微妙又深刻的方式改進我們的開發體驗,勢將改進效率,減小我們需要鍵入的程式碼量。
在下幾個星期裡,我將試著在部落格裡討論幾個這些語言的改進之處,示範如何把它們使用在一起,來產生一些非常強有力的結果。
新的C#語言特性:自動屬性實作(Automatic Properties)
如果你現在是C#開發人員的話,你大概非常習慣編寫像下面這個程式碼片段一樣帶有基本屬性的型別:
private string _firstName;
private string _lastName;
private int _age;
public string FirstName {
get {
return _firstName;
}
set {
_firstName = value;
}
}
public string LastName {
get {
return _lastName;
}
set {
_lastName = value;
}
}
public int Age {
get {
return _age;
}
set {
_age = value;
}
}
}
注意,我們在屬性的geter/setter中實際上並沒有添加什麼邏輯,我們只是將get/set實施到了一個成員變數。我們不禁要問這樣一個問題:為什麼不直接使用成員變數而使用屬性呢?這是因為,向外面呈現公開的成員變數有很多不好的地方。二個最大的問題是:1) 你無法輕易地對成員變數做資料繫結,2) 如果你從類中向外呈現成員變數的話,之後,你不重新編譯那些引用老的類別的任何程式集,就無法將它們改成屬性(譬如,要添加驗證邏輯到setter裡)。
Orcas中發佈的新C#編譯器通過一個叫「自動屬性(automatic properties)」的語言特性提供了一個優雅的方式來使得你的編碼更加簡潔,同時還保持屬性的彈性。自動屬性允許你避免手工宣告一個私有成員變數以及編寫get/set邏輯,取而代之的是,編譯器會自動為你生成一個私有變數和預設的get/set 操作。
譬如,使用自動屬性,我現在可以將上面的程式碼改寫成:
public string FirstName {
get; set;
&n
bsp; }
public string LastName {
get; set;
}
public int Age {
get; set;
}
}
或者,我想更簡明的話,我可以將空白的地方做進一步壓縮,像這樣:
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
}
當Orcas版中的C#編譯器遇上像上面這樣的空的get/set屬性的話,它會自動為你在類中生成一個私有成員變數,對這個變數實現一個公開的getter 和setter。這麼做的好處是,從型別-合約(type-contract)的角度來看,這個類跟我們上面第一個有點冗長的實現看上去完全一樣,這意味著,不像公開的成員變數,在將來,我可以在我的屬性setter實現中添加驗證邏輯,而不用對引用我的類別的任何外部元件做改動。
Bart De Smet對使用Orcas三月份CTP版中的自動屬性時內部發生的情形作了精彩的描述,你可以在這裡閱讀他的精彩相關文章。
C#和VB語言的新特性:物件初始化器(Object Initializers)
.NET框架中的型別非常依賴於屬性的使用。當生成物件實例和使用新的型別時,寫出像下面這樣的編碼是非常常見的情形:
person.FirstName = 「Scott」;
person.LastName = 「Guthrie」;
person.Age = 32;
你有沒有想要把這樣的編碼簡化過(也許將其安排在一行上)?使用Orcas中的C#和VB語言編譯器的話,你現在可以利用一個稱為「物件初始化器(object Initializers)」的「語法糖(syntactic sugar)」語言特性來做些簡化,將上述程式碼覆寫為:
然後,編譯器就會自動地生成合適的屬性setter程式碼,保持跟前面較冗長的程式碼例子同樣的語意。
除了在初始化類時設置簡單的屬性值外,物件初始化器特性也允許我們設置更複雜的巢狀 (nested) 屬性型別。譬如,假如我們在上面定義的每個Person型別也擁有一個屬於Address型別的叫「Address」的屬性。我們可以編寫下面這樣的程式碼來生成一個新的Person物件,同時設置它的屬性,像這樣:
FirstName = 「Scott」,
LastName = 「Guthrie」
Age = 32,
Address = new Address {
Street = 「One Microsoft Way」,
City = 「Redmond」,
State = 「WA」,
Zip = 98052
}
};
Bart De Smet對使用Orcas三月份CTP版中的物件初始化器時內部發生的情形也作了精彩的描述,你可以在這裡閱讀他的精彩相關文章。
C#和VB語言的新特性:集合初始化器(Collection Initializers)
物件初始化器很棒,它極大地簡化了把物件添加到集合的做法。譬如,假如我要把三個人加到一個基於泛型的型別為Person的List集合中去的話,我可以寫下面這樣的編碼:
people.Add( new Person { FirstName = 「Scott」, LastName = 「Guthrie」, Age = 32 } );
people.Add( new Person { FirstName = 「Bill」, LastName = 「Gates」, Age = 50 } );
people.Add( new Person { FirstName = 「Susanne」, LastName = 「Guthrie」, Age = 32 } );
對這個例子,跟我使用C# 2.0編譯器要輸入的程式碼相比,單獨使用新的物件初始化器特性就能省去12行額外的程式碼。
但Orcas版中的C#和VB編譯器允許我們更進一步,現在同時支援「集合初始化器(collection initializers)」,這允許我們避免要寫多個Add語句,省下更多的鍵盤操作:
new Person { FirstName = 「Scott」, LastName = 「Guthrie」, Age = 32 },
new Person { FirstName = 「Bill」, LastName = 「Gates」, Age = 50 },
new Person { FirstName = 「Susanne」, LastName = 「Guthrie」, Age = 32 }
};
當編譯器遇上上面這樣的句法時,它會自動為我們生成像前面的例子一樣的集合插入編碼。
結語
作為開發人員,我們現在擁有了簡明得多的方式來定義物件,對它們初始化,將它們加入集合內。在運行時,其語意,跟今天的較長的版本的語意,是完全一樣的(所以你不必擔心行為會改變)。但現在你不需輸入那麼多字元了,你的程式碼將既乾淨又簡明。
在不遠的將來,我將發表更多的部落格文章來討論Orcas版中更多的語言上的改進,包括擴充方法(Extension Methods),Lambdas和匿名類。然後,我將對LINQ做深入討論,示範它是如何利用所有這些特性來提供一個非常優雅的方式來查詢和與資料交互的。
希望本文對你有所幫助,
Scott