基於Visual Studio2010講解C 4個新特性
Csharp4.0與以往版本的基礎了體現了強大的效能優勢,主要體現於四個方面:
1. 通過委託成員來實現介面
在C# 4.0中可以通過委託來實現某個成員的介面,例如下面的程式碼:
[c-sharp] view plain copy print?- publicclass Foo : IList
- {
- private List _Collection implements IList;
- public Foo()
- {
- _Collection = new List();
- }
- }
被封閉的成員可以用委託實現一個或多個介面,多個介面用逗號分隔。這麼做可以去掉很多冗餘的程式碼,就像上面的示例,不再需要在封閉類(Foo類)上寫一大堆方法來將介面實現交給成員變數,介面的實現會直接對映到受委託的介面實現(_Collection成員變數)。這個功能同樣增強了對minxins的支援。
這個就是“委託模式”了,wikipedia上對此模式的解釋如下:
委託模式是指一個物件對外表現某種行為,但事實上只是將實現此行為的任務將會給一個相關的成員的技術,這種技術反轉了責任。委託模式是加強組合 (聚合)、minxins及aspects的一種基本模式。
再進一步,在委託實現介面之餘,我們也應當可以自由地重寫某些方法如下:
[c-sharp] view plain copy print?- publicclass Foo : IList
- {
- private List _Collection { get; set; } implements IList;
- public
- {
- _Collection = new List();
- }
- //這將覆蓋委託的執行
- // 漂亮的混入和方便的功能
- pattern implementation
- publicint IList.Add(string value)
- {
- if (!_Collection.Contains(value))
- _Collection.Add(value);
- }
- }
2. 匿名返回型別
在C#中匿名型別可以擁有像普通的類宣告一樣的地位。(當前)匿名型別只能用於區域性變數,不能作為方法的返回值。但是如果一個強型別的LINQ查詢的返回型別可以作為方法的返回型別一定很好,比如下面的程式碼:
[c-sharp] view plain copy print?- public var GetProductInfos()
- {
- var productInfos =
- from p in products
- select new { p.ProductName, p.Category, Price = p.UnitPrice };
- return productInfos;
- }
3. 一些 Duck-typing or Structural Subtyping 型別的支援
如果一個類中的某一個方法/屬性的簽名和某個介面一樣,並且這個類沒有實現此介面,那麼這個類就將隱式地實現這個介面。只有這個類實現了介面規定的所有方法/屬性的時候才被認為隱式地實現了此介面。
如果這東西走起來像鴨子,晃起來像鴨子,那麼這就是鴨子!(James Riley)
那麼這個和Structural Subtyping有什麼區別?我承認structural subtyping更適合C#的靜態樣式,所以這是個'static duck typing',或者如wikipedia所述:
Duck typing與structural typing的區別僅在於型別中被訪問的部分在執行期才做相容性確認。
我們將通過一個用例來說明這種方法有什麼好處:
在.NET框架中,一部分控制元件實現了一個叫ReadOnly的屬性,比如TextBox, DataGrid, NumericUpDown
現在我們建一個叫IReadOnlyRestricable的介面
[c-sharp] view plain copy print?- publicinterface IReadOnlyRestricable
- {
- bool ReadOnly { get; set; }
- }
然後我們要遍歷所有的控制元件,找出有ReadOnly屬性的控制元件並把此屬性設為true(這些控制元件本身沒有實現IReadOnlyRestricable),在ducktyping下我們可以把控制元件通過型別轉換為IReadOnlyRestricable,就像下面程式碼一樣,這樣我們就不需要通過反射去定位ReadOnly屬性了:
[c-sharp] view plain copy print?- foreach (Control c in f.Controls)
- {
- //希望有隱式轉換
- IReadOnlyRestrictable ifinterface contract isinclass we are checking against
- IReadOnlyRestricable editable = c as IReadOnlyRestricable;
- if (editable != null)
- editable.ReadOnly = true;
- }
在我看來ducktyping的最大好處是可以為你不需要訪問的類庫定義一些介面,這可以儘可能地減少相互依賴,你可以檢視Phil Haacks more extensive post on duck typing這文章來看看為什麼作者相信這對C#有好處。
Krzysztof Cwalina認為,很顯然的,C#的foreach關鍵字已經使用了duck typing.
4. 安全的null延遲賦值操作符
我很想看到一種安全地訪問一個值為null的物件的屬性的表示式,表示式可能形如Object.Property.Property.Value
比如我要訪問Customer?.FirstName,但是Customer是null,此時Customer?.FirstName會返回null而不是丟擲個NullReferenceException
再看看下面的程式碼,你就會知道怎麼用了:
[c-sharp] view plain copy print?- //如果不是客戶或命令無效,這將丟擲一個像往常一樣空引用異常
- int orderNumber = Customer.Order.OrderNumber;
- //這將無法編譯,因為它需要一個空的返回型別
- int orderNumber = Customer.Order?.OrderNumber;
- //這將返回null,如果客戶是空或者如果命令是空
- int? orderNumber = Customer?.Order?.OrderNumber;
- if (orderNumber.HasValue)
- //... 用它做一些事情
- //而不是必須做
- if ((Customer != null) && (Customer.Order != null))
- int a = Customer.Order.OrderNumber