在C# 3.0中,幾乎每個新特性都是為LINQ服務的。所以,本文將介紹下面幾個在C# 3.0中引入的新特性:
其實這幾個特性都是比較容易理解的,對於這幾個特性,編譯器幫我們做了更多的事情(想想匿名方法和迭代器塊),從而簡化我們的代碼。
在C# 3.0以前,當我們定義屬性的時候,一般使用下面的代碼
public class Book { private int _id; private string _title; public int Id { get { return _id; } set { _id = value; } } public string Title { get { return _title; } set { _title = value; } } }
在C# 3.0中引入了自動實現的屬性,編譯器會幫我們做更多的轉換,所以我們可以把上面的屬性實現代碼轉換為:
public class Book { public int Id { get; set; } public string Title { get; set; } }
在使用了自動實現的屬性之後,代碼變短了,我們也沒有必要再定義私有的字段。
其實,當查看過IL代碼之後就會發現這裡編譯器幫我們定義了私有字段,實現了get/set方法。
注意,當使用結構的時候,如果要使用自動屬性,會有一個小問題:所有的構造函數都需要顯式地調用無參數的構造函數this(),只有這樣,編譯器才知道所有的字段都被明確的賦值了。
例如下面代碼中,當我們刪除":this()"後,編譯器就會報錯。
public struct Student { public int Id { get; set; } public string Name { get; set; } public string Gender { get; set; } //在結構中使用自動屬性一定要顯式地調用無參數的構造函數this() public Student(string name):this() { this.Name = name; } }
C# 1.0和C# 2.0中的類型系統是靜態、顯示和安全的。
在C# 3.0中我們可以使用var關鍵字定義隱式類型的變量,但是變量仍然是靜態類型,只是編譯器可以幫助我們推斷變量的類型。
下面看一段代碼,使用隱式類型的語句跟注釋掉的語句的IL代碼是相同的:
static void Main(string[] args) { var str = "hello world";//string str = "hello world"; var num = 9;// int num = 9; Console.WriteLine(str.GetType()); Console.WriteLine(num.GetType()); Console.Read(); }
通過代碼的輸出可以看到,每個隱式類型的變量都是靜態類型(同樣我們也可以通過VS單步調試來查看隱式類型變量的類型),在這裡是編譯器幫我們做了類型推斷。
為了驗證這一點,但我們給str變量賦一個整型的值時,就會得到一個"Cannot implicitly convert type 'int' to 'string'"的錯誤。
static void Main(string[] args) { var str = "hello world";//string str = "hello world"; str = 9; Console.Read(); }
使用隱式類型的時候,會有一些限制,不是所有變量都能使用隱式類型:
有些時候使用隱式類型可以減少代碼長度,通過不影響代碼可讀性,反而使我們把注意力放在了更有用的代碼上;但是,有時候隱式類型會是代碼可讀性變差。所以要自己衡量什麼時候使用隱式類型的變量。下面看一個簡單的例子
static void Main(string[] args) { //簡化了代碼,沒有犧牲可讀性 var wordCount = new Dictionary<string, int>(); foreach (var dict in wordCount) { Console.WriteLine("number of {0} is {1}", dict.Key, dict.Value); } //可讀性變差,不容易從代碼中直接看出變量類型 var numA = 2147483647; var numB = 2147483648; var numC = 4294967295; Console.WriteLine(numA.GetType()); Console.WriteLine(numB.GetType()); Console.WriteLine(numC.GetType()); Console.Read(); }
在C# 3.0中,我們有了新的對象和集合初始化的方法。
當我們有了對象初始化程序的時候,對象初始化的代碼就變得更加直觀、簡單。看一個例子:
public class Book { public int Id { get; set; } public string Title { get; set; } //如果沒有默認的構造函數,使用對象初始化時就會報錯 public Book() { } public Book(string title) { this.Title = title; } } class Program { static void Main(string[] args) { //C# 3.0之前初始化對象的方法 Book b1 = new Book(); b1.Id = 1; b1.Title = "C# step by step"; //使用對象初始化程序 Book b2 = new Book(){Id = 2, Title = "C# in depth"}; Book b3 = new Book { Id = 3, Title = "C# in depth" }; Book b4 = new Book("C# in depth") { Id = 1}; } }
當我們查看IL代碼會發現,b1、b2和b3的IL代碼完全一樣。
更多詳情見請繼續閱讀下一頁的精彩內容: http://www.linuxidc.com/Linux/2015-02/114146p2.htm