C# 語言歷史版本特性(C# 1.0到C# 8.0匯總)

C# 1.0 特性
Classes:面向?qū)ο筇匦?,支持類類?br> Structs:結(jié)構(gòu)
Interfaces:接口
Events:事件
Properties:屬性,類的成員,提供訪問字段的靈活方法
Delegates:委托,一種引用類型,表示對具有特定參數(shù)列表和返回類型的方法的引用
Expressions,Statements,Operators:表達(dá)式、語句、操作符
Attributes:特性,為程序代碼添加元數(shù)據(jù)或聲明性信息,運(yùn)行時(shí),通過反射可以訪問特性信息
Literals:字面值(或理解為常量值),區(qū)別常量,常量是和變量相對的
C# 2.0 特性 (VS 2005)
Generics:泛型
Partial types:分部類型,可以將類、結(jié)構(gòu)、接口等類型定義拆分到多個(gè)文件中
Anonymous methods:匿名方法
Iterators:迭代器
Nullable types:可以為Null的類型,該類可以是其它值或者null
Getter/setter separate accessibility:屬性訪問控制
Method group conversions (delegates):方法組轉(zhuǎn)換,可以將聲明委托代表一組方法,隱式調(diào)用
Co- and Contra-variance for delegates and interfaces:委托、接口的協(xié)變和逆變
Static classes:靜態(tài)類
Delegate inference:委托推斷,允許將方法名直接賦給委托變量
C# 3.0 特性(VS 2008)
Implicitly typed local variables:
Object and collection initializers:對象和集合初始化器
Auto-Implemented properties:自動(dòng)屬性,自動(dòng)生成屬性方法,聲明更簡潔
Anonymous types:匿名類型
Extension methods:擴(kuò)展方法
Query expressions:查詢表達(dá)式
Lambda expression:Lambda表達(dá)式
Expression trees:表達(dá)式樹,以樹形數(shù)據(jù)結(jié)構(gòu)表示代碼,是一種新數(shù)據(jù)類型
Partial methods:部分方法
C# 4.0特性 (VS 2010)
Dynamic binding:動(dòng)態(tài)綁定
Named and optional arguments:命名參數(shù)和可選參數(shù)
Generic co- and contravariance:泛型的協(xié)變和逆變
Embedded interop types (“NoPIA”):開啟嵌入類型信息,增加引用COM組件程序的中立性
C# 5.0特性 (VS 2012)
Asynchronous methods:異步方法
Caller info attributes:調(diào)用方信息特性,調(diào)用時(shí)訪問調(diào)用者的信息
C# 6特征 (VS 2015)
Compiler-as-a-service (Roslyn)
Import of static type members into namespace:支持僅導(dǎo)入類中的靜態(tài)成員
Exception filters:異常過濾器
Await in catch/finally blocks:支持在catch/finally語句塊使用await語句
Auto property initializers:自動(dòng)屬性初始化
Default values for getter-only properties:設(shè)置只讀屬性的默認(rèn)值
Expression-bodied members:支持以表達(dá)式為主體的成員方法和只讀屬性
Null propagator (null-conditional operator, succinct null checking):Null條件操作符
String interpolation:字符串插值,產(chǎn)生特定格式字符串的新方法
nameof operator:nameof操作符,返回方法、屬性、變量的名稱
Dictionary initializer:字典初始化
C# 7.0 特征 (Visual Studio 2017)
Out variables:out變量直接聲明,例如可以out in parameter
Pattern matching:模式匹配,根據(jù)對象類型或者其它屬性實(shí)現(xiàn)方法派發(fā)
Tuples:元組
Deconstruction:元組解析
Discards:沒有命名的變量,只是占位,后面代碼不需要使用其值
Local Functions:局部函數(shù)
Binary Literals:二進(jìn)制字面量
Digit Separators:數(shù)字分隔符
Ref returns and locals:引用返回值和局部變量
Generalized async return types:async中使用泛型返回類型
More expression-bodied members:允許構(gòu)造器、解析器、屬性可以使用表達(dá)式作為body
Throw expressions:Throw可以在表達(dá)式中使用
C# 7.1 特征 (Visual Studio 2017 version 15.3)
Async main:在main方法用async方式
Default expressions:引入新的字面值default
Reference assemblies:
Inferred tuple element names:
Pattern-matching with generics:
**C# 8.0 特征 (Visual Studio 2017 version 15.7)
Default Interface Methods 缺省接口實(shí)現(xiàn)
Nullable reference type NullableReferenceTypes 非空和可控的數(shù)據(jù)類型
Recursive patterns 遞歸模式
Async streams 異步數(shù)據(jù)流
Caller expression attribute 調(diào)用方法表達(dá)式屬性
Target-typed new
Generic attributes 通用屬性
Ranges
Default in deconstruction
Relax ordering of ref and partial modifiers




C#5.0版本

像C#4.0版本一樣,C#5.0版本中沒有太多功能 - 但是其中一個(gè)功能非常龐大。

  • 異步/等待
  • CallerInfoAttributes

當(dāng)C#5.0發(fā)布時(shí),它實(shí)際上改變了C#開發(fā)人員編寫異步代碼的方式。雖然直到今天仍然有很多困惑,但我在這里向您保證,這比大多數(shù)人想象的要簡單得多。這是C#的一個(gè)重大飛躍 - 它引入了一個(gè)語言級別的異步模型,它極大地賦予了開發(fā)人員編寫外觀和感覺同步(或者至少是連續(xù)的)的“異步”代碼。

異步編程在處理I/O綁定工作負(fù)載(如與數(shù)據(jù)庫,網(wǎng)絡(luò),文件系統(tǒng)等進(jìn)行交互)時(shí)非常強(qiáng)大。異步編程通過使用非阻塞方法幫助處理吞吐量。這種方法使用了一個(gè)透明的異步狀態(tài)機(jī)中的掛點(diǎn)和相應(yīng)的延續(xù)。

同樣,如果CPU負(fù)載計(jì)算的工作量很大,則可能需要考慮異步執(zhí)行此項(xiàng)工作。這將有助于用戶體驗(yàn),因?yàn)閁I線程不會被阻塞,而是可以自由地響應(yīng)其他UI交互。

編者注:這里有一些關(guān)于C#異步編程的最佳實(shí)踐,使用Async Await.

在C#5.0中,當(dāng)語言添加了兩個(gè)新的關(guān)鍵字async和await時(shí),異步編程被簡化了。這些關(guān)鍵字適用于Task。下表將作為參考:

Task表示異步操作。操作可以通過Task返回值,也可以通過Task返回void。當(dāng)您使用async關(guān)鍵字修飾Task返回方法時(shí),它使方法主體可以使用await關(guān)鍵字。當(dāng)您請求await關(guān)鍵字的返回值時(shí),控制流將返回給調(diào)用者,并且在方法的那個(gè)點(diǎn)執(zhí)行暫停。當(dāng)await的操作完成后,在同一點(diǎn)上恢復(fù)執(zhí)行。部分代碼如下!

class IOBoundAsyncExample
{
  
    private const string Url = "http://api.icndb.com/jokes/random?limitTo=[nerdy]";
 
    internal async Task GetJokeAsync()
    {
        using (var client = new HttpClient())
        {
            var response = await client.GetStringAsync(Url);
            var result = JsonConvert.DeserializeObject(response);
 
            return result.Value.Joke;
        }
    }
}
public class Result
{
    [JsonProperty("type")] public string Type { get; set; }
    [JsonProperty("value")] public Value Value { get; set; }
}
 
public class Value
{
    [JsonProperty("id")] public int Id { get; set; }
    [JsonProperty("joke")] public string Joke { get; set; }
}

我們用一個(gè)名為GetJokeAsync的方法定義一個(gè)簡單的類。該方法是返回Task,這意味著我們的GetJokeAsync方法最終會給您一個(gè)字符串,或者可能出錯(cuò)。
該方法使用async關(guān)鍵字進(jìn)行修飾,該關(guān)鍵字允許使用等待關(guān)鍵字。我們實(shí)例化并使用一個(gè)HttpClient對象。然后我們調(diào)用GetStringAsync函數(shù),它接受一個(gè)字符串url并返回一個(gè)Task 。我們等待從GetStringAsync調(diào)用返回的Task。
當(dāng)響應(yīng)已經(jīng)準(zhǔn)備好時(shí),就會繼續(xù)發(fā)生并控制從我們曾經(jīng)掛起的位置恢復(fù)。然后,我們將JSON反序列化到Result類的實(shí)例中,并返回Joke屬性。

一些我最喜歡的成果

查克·諾里斯(Chuck Norris)可以用單一的斷言來測試整個(gè)應(yīng)用程序。
查克·諾里斯(Chuck Norris)可以編譯語法錯(cuò)誤。
項(xiàng)目經(jīng)理永遠(yuǎn)不會要求查克·諾里斯(Chuck Norris)做出估計(jì)。
歡鬧隨之而來!我們了解了C#5.0的驚人的異步編程模型。

C#6.0版本

C#6.0的推出有很多很大的進(jìn)步,很難選擇我最喜歡的功能。

  • 字典初始化
  • 異常過濾器
  • 在屬性里使用Lambda表達(dá)式
  • nameof表達(dá)式
  • 空值運(yùn)算符
  • 自動(dòng)屬性初始化
  • 靜態(tài)導(dǎo)入
  • 字符串嵌入值
    我把范圍縮小到三個(gè)突出特點(diǎn):空值運(yùn)算符,字符串嵌入值和nameof表達(dá)式。
    雖然nameof表達(dá)式很棒,我?guī)缀趺看味加盟鼇砭帉懘a,但其他兩個(gè)特性更有影響力。這讓我在字符串嵌入值和空值運(yùn)算符之間做出決定,這是相當(dāng)困難的。我決定我最喜歡的是字符串嵌入值,這就是為什么。
    空值運(yùn)算符是偉大的,它允許我寫較少的詳細(xì)代碼,但它不一定能防止我的代碼中的錯(cuò)誤。但是,使用字符串嵌入值可以防止運(yùn)行時(shí)錯(cuò)誤 - 這是我的書中的一個(gè)勝利。
    使用$符號啟動(dòng)字符串文字時(shí),將啟用C#中的字符串嵌入值語法。這指示C#編譯器打算用各種C#變量,邏輯或表達(dá)式來插入此字符串。這是手動(dòng)字符串連接甚至是string.Format方法的一個(gè)主要升級??紤]以下:
{
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public override string ToString()
        => string.Format("{0} {1}", FirstName);
}

我們有一個(gè)簡單的Person類,具有兩個(gè)名稱屬性,用于名字和姓氏。我們重寫ToString方法并使用string.Format。問題是,編譯時(shí),由于開發(fā)人員顯然希望將姓氏也作為結(jié)果字符串的一部分,因此很容易出錯(cuò),這一點(diǎn)在“{0} {1} ”參數(shù)中很明顯。同樣,開發(fā)人員可以很容易地交換名稱或正確提供兩個(gè)名稱參數(shù),但混亂的格式文字只包括第一個(gè)索引,等等...現(xiàn)在我們可以考慮使用字符串嵌入值。

class Person
{
    public string FirstName { get; set; } = "David";
    public string LastName { get; set; } = "Pine";
    public DateTime DateOfBirth { get; set; } = new DateTime(1984, 7, 7);

    public override string ToString()
        => $"{FirstName} {LastName} (Born {DateOfBirth:MMMM dd, yyyy})";
}

我冒昧添加DateOfBirth屬性和一些默認(rèn)的屬性值。另外,我們現(xiàn)在在我們的ToString方法的覆蓋中使用字符串嵌入值。作為一名開發(fā)人員,犯上述錯(cuò)誤要困難得多。最后,我也可以在插值表達(dá)式中進(jìn)行格式化。注意第三次嵌入值,DateOfBirth是一個(gè)DateTime - 因此我們可以使用您已經(jīng)習(xí)慣的所有標(biāo)準(zhǔn)格式。只需使用:運(yùn)算符來分隔變量和格式。

示例輸出

· David Pine (Born July 7, 1984)

編輯注:有關(guān)C#6.0新特性的詳細(xì)內(nèi)容,請閱讀www.dotnetcurry.com/csharp/1042/csharp-6-new-features

C#7.0版本

從所有集成到 C# 7.0的特性中。

  • 更多的函數(shù)成員的表達(dá)式體
  • 局部函數(shù)
  • Out變量
  • 模式匹配
  • 局部變量和引用返回
  • 元組和解構(gòu)
    我結(jié)束了模式匹配,元組和Out變量之間的爭論。我最終選擇了Out變量,這是為什么。
    模式匹配但是我真的不經(jīng)常使用它,至少現(xiàn)在還沒有。也許以后我會更多地使用它,但是對于我迄今為止編寫的所有c#代碼,沒有太多地方可以利用它。同樣,這是一個(gè)很棒的功能,我確實(shí)看到了它的位置 - 只是在C#7.0中這不是我最喜歡的。
    元組也是一個(gè)很好的補(bǔ)充。元組是語言的重要組成部分,成為一流的公民是非常棒的。我會說,“寫tem1,.Item2,.Item3等...的日子已經(jīng)過去了,但這并不一定是正確的。反序列化失去了元組的名稱,使得這個(gè)公共API不那么有價(jià)值
    我也不喜歡ValueTuple類型是可變的這一事實(shí)。我只是不明白設(shè)計(jì)者的決定。我希望有人能給我解釋一下,但感覺有點(diǎn)像疏忽。因此,我得到了選擇out變量的特性。
    自從C#版本1.0以來,try-parse模式已經(jīng)在各種值類型中出現(xiàn)了。模式如下:
public boolean TryParse(string value, out DateTime date)
{
    // 為了簡便起見,我們省略了.....
}

該函數(shù)返回一個(gè)布爾值,指示給定的字符串值是否能夠被解析。如果為true,則將分析的值分配給生成的輸出參數(shù)date。它的使用如下:

DateTime date;
if (DateTime.TryParse(someDateString, out date))
{
    //  date現(xiàn)在是解析值
}
else
{
    // date是DateTime.MinValue,默認(rèn)值
}

這種模式是有用的,但有點(diǎn)麻煩。有時(shí),不管解析是否成功,開發(fā)人員都會采取相同的操作過程。有時(shí)使用默認(rèn)值是可以的。C#7.0中的out變量使得這個(gè)更復(fù)雜,不過在我看來不那么復(fù)雜。
示例如下:

if (DateTime.TryParse(someDateString, out var date))
{
    // date現(xiàn)在是解析值
}
else
{
    // date是DateTime.MinValue,默認(rèn)值
}

現(xiàn)在我們移除了if語句塊的外部聲明,并把聲明作為參數(shù)本身的一部分。使用var是合法的,因?yàn)轭愋褪且阎?。最后,date變量的范圍沒有改變。它從內(nèi)聯(lián)聲明泄漏到if塊的頂部。
你可能會問自己:“為什么這是他最喜歡的功能之一?”.....這種感覺真的沒有什么變化。
但是這改變了一切!
它使我們的C#更具有表現(xiàn)力。每個(gè)人都喜歡擴(kuò)展方法,對 - 請考慮以下幾點(diǎn):

public static class StringExtensions
{
    private delegate bool TryParseDelegate(string s, out T result);

    private static T To(string value, TryParseDelegate parse)
        => parse(value, out T result) ? result : default;

    public static int ToInt32(this string value)
        => To(value, int.TryParse);

    public static DateTime ToDateTime(this string value)
        => To(value, DateTime.TryParse);

    public static IPAddress ToIPAddress(this string value)
        => To(value, IPAddress.TryParse);

    public static TimeSpan ToTimeSpan(this string value)
        => To(value, TimeSpan.TryParse);
}

這個(gè)擴(kuò)展方法類很簡潔,表達(dá)能力強(qiáng)。在定義了遵循try-parse模式的私有委托之后,我們可以編寫一個(gè)泛型復(fù)合函數(shù),它需要一個(gè)泛型類型的參數(shù)、要解析的字符串值和TryParseDelegate?,F(xiàn)在我們可以安全地依賴這些擴(kuò)展方法,考慮以下幾點(diǎn)::

public class Program
{
    public static void Main(string[] args)
    {
        var str =
            string.Join(
                "",
                new[] { "James", "Bond", " +7 " }.Select(s => s.ToInt32()));

        Console.WriteLine(str); // 打印 "007"
    }
}

要了解C#7的所有新功能,請查看本教程www.dotnetcurry.com/csharp/1286/csharp-7-new-expected-features

結(jié)論

這篇文章對我個(gè)人而言頗具挑戰(zhàn)性。我喜歡C#的許多特性,因此每次發(fā)布只收集一個(gè)最喜歡的內(nèi)容是非常困難的。

每個(gè)較新版本的C#都包含了強(qiáng)大而有影響力的功能。C#語言團(tuán)隊(duì)以無數(shù)的方式進(jìn)行創(chuàng)新 - 其中之一就是引入點(diǎn)發(fā)布。在撰寫本文時(shí),C# 7.1和 7.2已正式發(fā)貨。作為C#開發(fā)人員,我們生活在一個(gè)激動(dòng)人心的語言時(shí)代!

然而,對我來說,對所有這些特性進(jìn)行分類是相當(dāng)有見地的;因?yàn)樗鼛椭覀兞私饬耸裁词菍?shí)際的,最影響我的日常發(fā)展。一如既往,努力成為一個(gè)務(wù)實(shí)的開發(fā)者!并不是語言中所有可用的特性都是當(dāng)前任務(wù)所必需的,但了解什么是可用的,這一點(diǎn)很重要。

當(dāng)我們期待C#8的建議和原型時(shí),我對C#的未來感到興奮。它看起來確實(shí)很有希望,而且語言正在積極地試圖緩解“價(jià)值億萬美金的錯(cuò)誤”。

轉(zhuǎn)載自http://www.manongjc.com/article/44646.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容