標籤:des style blog http io ar color 使用 sp
VS2015的預覽版在11月12日發布了,下面讓我們來看看C#都提供了哪些新的功能。
字串添寫(String interpolation)
在格式化字串時,string.Format是經常被用到的,它確實很方便使用,但是這種使用預留位置,然後通過參數替換的方式還不夠方便, 在C#6.0裡,String interpolation文法的引入提供了另一種格式化字串的方式。請看下面的例子:
假設我們現在有個如下所示的Book類,現在需要格式化它的欄位以輸出關於該book的描述。
public class Book{ public int Number { get; set; } public string Name { get; set; } public string Abstract { get; set; } public float Price { get; set; } public List<Author> Authors { get; set; }}
使用string.Format的代碼如下:
var introUsingStringFormat = string.Format("[{0}]‘ price is {1:F3}, its description is {2}.", book.Name, book.Price, book.Abstract);
使用string interpolation的代碼如下:
var introUsingStrInterPolation = "[\{book.Name}]‘ price is \{book.Price : F3}, its description is \{book.Abstract}.";
完整的程式如下:
public void Show(){ //interpolate string var book = new Book { Abstract = "Book about C#6.0", Name = "C#6.0 new feature", Price = 10.8709f, }; var introUsingStrInterPolation = "[\{book.Name}]‘ price is \{book.Price : F3}, its description is \{book.Abstract}."; var introUsingStringFormat = string.Format("[{0}]‘ price is {1:F3}, its description is {2}.", book.Name, book.Price, book.Abstract); Console.WriteLine("format string using string interpolation:"); Console.WriteLine(introUsingStrInterPolation); Console.WriteLine("==============================================================================="); Console.WriteLine("format string using string.Format method:"); Console.WriteLine(introUsingStringFormat); Console.Read();}
如,兩種方式的輸出是一樣的:
總結:
String Interpolation文法允許你在字串裡直接插入代碼並可以像string.Format 那樣指定format Specifier和對齊,如上面的例子\{book.Price : F3}指定price的精度為3。這個文法在之後版本中會變得更加簡潔,可能會採用如下的格式:
var introUsingStrInterPolation = $"[{book.Name}]‘ price is {book.Price : F3}, its description is {book.Abstract}.";
空條件運算子?
如下面例子所示, 在程式中經常會出現對錶達式中對象是否為空白的連續檢測。
if (book != null && book.Authors != null) { var countOfAuthers = book.Authors.Count; }
空條件運算子?使得這種檢測更加方便,表達更加簡潔,其使用方法如下:
var countOfAuthersUsingNullConditional = book?.Authors?.Count;
空條件運算子?用在成員運算子.和索引前面,會執行下面的操作:
如果其前面的對象為空白,那麼直接返回null,否則允許訪問前面對象的成員或者元素以繼續後面運算,所以上面的運算式和下面的程式碼片段是等價的
if (book == null) { countOfAuthorsUsingNullConditional = null; } else if (book.Authors == null) { countOfAuthorsUsingNullConditional = null; } else { countOfAuthorsUsingNullConditional = book.Authors.Count; }
上面的code展示了其執行的邏輯順序,達到相同結果的簡潔寫法如下:
if(book == null || book.Authors == null){ countOfAuthorsUsingNullConditional = null;}else { countOfAuthorsUsingNullConditional = book.Authors.Count;}
從上可以看出其具有如下特性:
- 包含?的運算式返回的是參考型別
- ?具有類似邏輯運算子||和&&的短路邏輯
- ?自己可以組成鏈,正如上面例子所示的,在同一運算式中連續使用?
此外,空條件運算子還具有如下特點:
- 對其前面的對象是否為空白只進行一次計算
- 可以與合并運算子??一起使用更加方便
- ?後面不能直接跟隨使用()的方法調用,對於event或者delegate可以使用?.Invoke的方式來使用,由於?只計算其右邊部分一次並把其儲存到臨時變數中,所以它是安全執行緒的
下面來看一些針對2和3的例子:
//using with coalescing operator ??int numberOfAuthors = book?.Authors?.Count ?? 0;//using with delegate.action?.Invoke();
完整的程式如下:
public void Show(){ //traditional way if (book != null && book.Authors != null) { var countOfAuthors = book.Authors.Count; Console.WriteLine("===================using tranditional way=============="); Console.WriteLine(countOfAuthors); } //the way of using null-conditional operator. var countOfAuthorsUsingNullConditional = book?.Authors?.Count; Console.WriteLine("===================null-conditional operator=============="); Console.WriteLine(countOfAuthorsUsingNullConditional); Console.Read(); //the logic of the expression. if (book == null) { countOfAuthorsUsingNullConditional = null; } else if (book.Authors == null) { countOfAuthorsUsingNullConditional = null; } else { countOfAuthorsUsingNullConditional = book.Authors.Count; } //the concise edition using tranditional way. if (book == null || book.Authors == null) { countOfAuthorsUsingNullConditional = null; } else { countOfAuthorsUsingNullConditional = book.Authors.Count; } //using with coalescing operator ?? int numberOfAuthors = book?.Authors?.Count ?? 0; //using with delegate. action?.Invoke(); }
nameof運算式
有時候我們需要獲得代碼中某些symbol的名字,例如在throw ArgumentNullException時,需要獲得為null參數的名字(字串形式),在調用PropertyChanged時,我們也需要獲得屬性的名字,直接使用字串具有如下的缺點:
- 容易拼字錯誤
- 無法重構
- 沒有語法檢查
nameof運算式能夠以字串的形式返回參數對象或者類成員的名字,下面是一些例子
var nameOfClassPropertyObject = nameof(book); var nameOfArgument = nameof(author); var classMethodMember = nameof(Book.Equals); var classPropertyMember = nameof(Book.Number); var @class = nameof(Book);
從上面的例子中可以看出nameof運算子可以用於類(包括attribute類),類的成員,對象上,另外需要注意的是它只會輸出最終元素的名字不會包含其首碼,例如nameof(Book.Equals)的輸出是Equals。
VS2015預覽版中的C#6.0 新功能(一)