C# 3.0新功能
• 隱式類型的本地變數和數組
• 物件初始設定式
• 集合初始設定式
• 自動實作屬性
• 匿名型別
• 擴充方法
• 分部方法定義
• Lambda 運算式
隱式類型的數組
var a = new[] { 1, 10, 100, 1000 }; // int[]
var b = new[] { "hello", null, " world" }; string[] 型的數組使用方括弧
var c = new[]
{
new[]{1,2,3,4},
new[]{5,6,7,8}
};
var d = new[]
{
new[]{"Luca", "Mads", "Luke", "Dinesh"},
new[]{"Karen", "Suma", "Frances"}
};
1.沒有在初始化語句的左側對隱式類
2.交錯數組就像一維數組那樣使用
3.不支援隱式類型的多維陣列
• var和匿名型別
class ImplicitlyTypedLocals2
{
static void Main()
{
string[] words = { "aPPLE", "BlUeBeRrY", "cHeRry" };
var upperLowerWords =
from w in words
select new { Upper = w.ToUpper(), Lower = w.ToLower() };
foreach (var ul in upperLowerWords)
{
Console.WriteLine("Uppercase: {0}, Lowercase: {1}", ul.Upper, ul.Lower);
}
} }
1.很多時候var是可以省略的
2.但在使用匿名型別初始設定變數時,必須使用它
• 物件初始設定式
使用物件初始設定式可以在建立對象時向對象的任何可訪問的
欄位或屬性分配值,而無需顯式調用建構函式
private class Cat
{
// Auto-implemented properties
public int Age { get; set; }
public string Name { get; set; }
}
static void MethodA()
{
// Object initializer
Cat cat = new Cat { Age = 10, Name = "Sylvester" };
}
3.由於只有編譯器知道匿名型別的名稱,因此必須在原始碼中使用var。
4.如果已經使用var 初始化了查詢變數,則還必須使用var 作為對查詢變
量進行逐一查看的foreach 語句中迭代變數的類型
• 將物件初始設定式用於匿名型別
查詢運算式經常使用匿名型別,而這些類型只能使用對象初始值
設定項進行初始化
var productInfos =
from p in products
select new { p.ProductName, p.UnitPrice };
建立匿名型別時重新命名欄位
select new {p.ProductName, Price = p.UnitPrice};
• 集合初始設定式
1.使用集合初始設定式可以在初始化一個實現了IEnumerable
的集合類時指定一個或多個項目初始設定式
2.項目初始設定式可以是簡單的值,也可以是運算式或對象初
始值設定項
3.通過使用集合初始設定式,無需在原始碼中指定多個對該類
的Add 方法的調用;編譯器會添加這些調用。
List<int> digits = new List<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
List<int> digits2 = new List<int> { 0 + 1, 12 % 3, MakeInt() };
List<int> digits = new List<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
List<int> digits2 = new List<int> { 0 + 1, 12 % 3, MakeInt() };
• 集合初始設定式
下面的集合初始設定式使用物件初始設定式來初始化在前面
的一個樣本中定義的Cat 類的對象。請注意,各個對象初始值設
定項被分別括在大括弧中,並且用逗號分隔。
List<Cat> cats = new List<Cat>
{
new Cat(){ Name="Sylvester", Age=8 },
new Cat(){ Name="Whiskers", Age=2},
new Cat() { Name="Sasha", Age=14}
};
List<Cat> moreCats = new List<Cat>
{
new Cat(){ Name="Furrytail", Age=5 },
new Cat(){ Name="Peaches", Age=4},
null
};
如果集合的Add 方法允許,可以將null 指定為集合初始值設定
項中的一個元素
• 自動實作屬性
– 當屬性訪問器中不需要其他邏輯時,自動實作屬性可使屬性聲
明變得更加簡潔
class LightweightCustomer
{
public double TotalPurchases { get; set; }
public string Name { get; private set; } // read-only
public int CustomerID { get; private set; } // read-only
}
自動實作屬性必須同時聲明get 和set 訪問器。若要建立readonly 自動實
現屬性,請給予它private set 訪問器。
自動實作屬性(Property) 不允許具有屬性(Attribute)。如果您必須在屬性
(Property) 的後備欄位上使用屬性(Attribute),則應該只建立常規屬性
(Property)。
• 匿名型別
– 匿名型別提供了一種方便的方法,可用來將一組唯讀屬性封裝到
單個對象中,而無需首先顯式定義一個類型。
– 類型名由編譯器產生,並且不能在原始碼級使用。
– 這些屬性的類型由編譯器推斷
var v = new { Amount = 108, Message = "Hello" };
– 匿名型別通常用在查詢運算式的select 子句中,以便返回源序列
中每個對象的屬性子集
– 匿名型別是使用new 運算子和物件初始設定式建立的
– 匿名型別是由一個或多個公用唯讀屬性群組成的類類型。不允許包
含其他種類的類成員(如方法或事件)。
• 匿名型別
– 最常見的方案是用其他類型的一些屬性初始化匿名型別
var productQuery =
from prod in products
select new { prod.Color, prod.Price };
foreach (var v in productQuery)
{
Console.WriteLine("Color={0}, Price={1}", v.Color, v.Price);
}
在將匿名型別分配給變數時,必須使用var 構造初始化該變數。
這是因為只有編譯器能夠訪問匿名型別的基礎名稱
• 匿名型別
– 匿名型別是直接從對象派生的參考型別。儘管應用程式無法訪問
匿名型別,但編譯器仍會為其提供一個名稱。
– 如果兩個或更多個匿名型別以相同的順序具有相同數量和種類的
屬性,則編譯器會將這些匿名型別視為相同的類型,並且它們共
享編譯器產生的相同類型資訊。
– 匿名型別具有方法範圍。
– 匿名型別不能像屬性一樣包含不安全類型。
– 由於匿名型別上的Equals 和GetHashCode 方法是根據屬性的
Equals 和GetHashcode 定義的,因此僅當同一匿名型別的兩個
執行個體的所有屬性都相等時,這兩個執行個體才相等。