C# 8小特性
對於C# 8,有吸引了大多數註意力的重大特性,如默認接口方法和可空引用,也有許多小特性被考慮在內。本文將介紹幾例可能加入C#未來版本的小特性。
新的賦值運算符:&&=和||=
從第一個版本開始,C#就支持把等號和另外一種運算符合在一起的語法。這幾乎包括除短路布爾運算符&&和||之外的所有的二元操作符(如+、-、&等)。“賦值運算符&&=和||=”提案是對這個列表的補充。
逐字內插字符串
逐字字符串以@"開頭。內插字符串使用$"。但是,如果你想要一個既逐字又內插的字符串呢?是用@$"還是$@"?目前,其中一個有效,另一個會報編譯器錯誤,但是,人們通常很難記住哪個是哪個。
在一個名為“逐字插入字符串”的中肯提案中,該語法將得到擴展,接受@$"。對它的解釋將和逐字插入字符串($@")完全相同,因此,你再也不用擔心弄反了。
關於這項修改,存在一些小爭議,因為有人認為這沒有必要或者會導致不一致。
允許using語句結構匹配IDisposable
接口與C#編譯器之間存在著奇怪的關系。經常,你不必為了使用一個語言特性而真正實現一個具體的抽象接口;你只需在類似抽象接口的類上創建一個公開的API。
典型的例子是“foreach”和IEnumerable。如果類有一個方法GetEnumerator,返回一個包含Current屬性和MoveNext方法的對象,那麽你就可以使用foreach。實際的返回類型不重要,這使得List<T>這樣的類似可以實現更快速的枚舉器。這通常稱為“結構匹配(structural matching)”。
在這個提案中,using語句也將支持結構匹配。這乍看之下沒什麽用,因為你不會希望看到一個可釋放類沒有實現IDisposable。不過,有一種名為ref struct的新類型。它們不能實現接口,因此,如果沒有這項提案,你在使用它們時就無法使用using語句。
和foreach與using共用的擴展方法
這個提案是前述提案的補充,是為了能夠把GetEnumerator或Dispose作為擴展方法添加,並且可以分別和“foreach”或“using”共用。再次,我們談論的這項特性僅用於非常特殊的情況。例如,你可以從第三方庫(這可能是調用Marshal.ReleaseComObject的好地方)向一個COM對象添加一個Dispose擴展方法。
這還不是一個正式的提案,可能會合並到前面提到的“using”語句修改中。
“using”語句隱式作用域
目前,“using”語句後面只能是一個顯式作用域(即一對花括號)或者另一個“using”語句。如果這個提案通過,你就可以編寫下面這樣的代碼:
using var a = new MyDisposable();
using var b = new MyDisposable();
using var c = new MyDisposable();
上述每個變量都會在當前作用域結束時以相反的順序自動釋放。從功能上說,這和下面的代碼等價,但更簡潔,也不會引入新作用域。
using (var a = new MyDisposable())
using (var b = new MyDisposable())
using (var c = new MyDisposable())
{
// 一些代碼
}
當需要多個可釋放對象而又不同時創建時,這項修改會特別有用。你甚至可以在表達式中間創建可釋放對象,而且可以確信,它將在當前作用域結束時釋放。
var results = myExcelReader.ReadResults(
using new MyExcelSheet(excelFilePath));
對於這項提案,其中一個批評是,它與某些語句如“goto”不兼容。
相關文章:
-
C# 8中的Async Streams
原文地址: http://www.infoq.com/cn/news/2018/09/csharp-8-small-features
C# 8小特性