最近再刷了一遍《深入理解C#》,比起上次刷生巡,好像只有泛型和Linq方面的知識(shí)加深了理解制轰,果然還是用的少的東西自然理解起來(lái)就困難一些晋被。今年C#的版本號(hào)已經(jīng)到了7.0怠苔,這本書(shū)的第三版是介紹到5.0,趁著這個(gè)機(jī)會(huì)把版本迭代中加入的語(yǔ)言特性做一個(gè)簡(jiǎn)要的總結(jié)
C# 1.x
不算后面的小版本號(hào)其實(shí)是可以統(tǒng)稱為C# 1的埋心,但是其實(shí)它包含了1.0和1.2兩個(gè)版本號(hào)(沒(méi)有1.1)指郁,分別在2002年和2003年發(fā)布。這個(gè)版本建立了C#語(yǔ)言的整體框架拷呆,面向?qū)ο笾械姆庋b闲坎、繼承、多態(tài)已經(jīng)得以很好的體現(xiàn)茬斧。
它當(dāng)時(shí)已經(jīng)提供了下面這些東西:
- 基礎(chǔ)數(shù)據(jù)類型腰懂,包含值類型和引用類型
- 非泛型的集合: * ArrayList *
- 事件和委托機(jī)制
- 多線程: * Thread *
- APM 異步編程模型: BeginXXX/EndXXX、IAsyncResult......
C# 2.0
C# 2.0版本是2005年末發(fā)布的项秉,最亮眼的特性自然就是* 泛型 * 绣溜,它也是.Net 2.0的CLR中最重要的特性,其他的一些特性也給開(kāi)發(fā)者提供了極大的便利娄蔼,還是用列表來(lái)總結(jié):
- 泛型怖喻,提供了參數(shù)化的類型的方法,也帶來(lái)了最常用的泛型集合贷屎,再也不需要考慮裝箱和拆箱帶來(lái)的性能損失了罢防。
- 可空類型艘虎,盡管只是語(yǔ)法糖,但是在語(yǔ)義化表達(dá)上是進(jìn)步的
- 匿名方法,對(duì)委托來(lái)說(shuō)是極大的語(yǔ)法簡(jiǎn)化
- 迭代器塊早芭,yield關(guān)鍵字
- 分部類 * partial class *
- 靜態(tài)類 * static class *
除了上面這些确买,還有些稍小的特性:
- EAP 基于事件的異步模式,支持異步調(diào)用中的取消和進(jìn)度報(bào)告(不算特性候生,但我想體現(xiàn)異步編程的發(fā)展歷程)
- 屬性讀寫(xiě)方法的訪問(wèn)修飾符獨(dú)立
string name;
public string Name
{
get { return name; }
private set { name = value; }
}
- 命名空間別名
- pragma
- 非安全代碼中固定大小的緩沖區(qū)(對(duì)于這條我是一知半解)
C# 3.0
C# 3.0中我們終于迎來(lái)了重量級(jí)的特性Linq同眯,我在Coding時(shí)常常感嘆,要是沒(méi)有Linq唯鸭,那得多寫(xiě)多少代碼须蜗。無(wú)論是Linq to Object還是的Linq to SQL、Linq to XML,實(shí)在是帶來(lái)了太多的便利明肮,帶來(lái)了實(shí)打?qū)嵉男噬系奶嵘?br> 3.0中包含了下面這些新特性:
- Linq
- 自動(dòng)屬性
- 隱式類型的局部變量: * var *
- 對(duì)象和集合的初始化器
var list = new List<string> { "AB","CD","EF" };
var tom = new Person { Name="Tom",Age=10 };
- 匿名類型
var tom = new { Name="Tom",Age=10 };
- Lambda表達(dá)式和表達(dá)式樹(shù)
- 拓展方法菱农,有了它Linq才是完整的,注意它是到.Net 3.5中才有的
- 分部方法柿估,它是C#類中的"鉤子"
C# 4.0
C# 4.0中的特性旨在提高互操作性循未,因此看起來(lái)更像是小修小補(bǔ)(除了動(dòng)態(tài)類型),它包括:
- 命名實(shí)參
- 可選參數(shù)
- 簡(jiǎn)化的COM交互性(還記得被Type.Missing支配的恐懼嗎)
- 泛型的可變性秫舌,協(xié)變和逆變獲得史詩(shī)級(jí)buff
- 動(dòng)態(tài)類型 * dynamic * 和與之對(duì)應(yīng)的DLR(這是個(gè)巨大的話題的妖,但平時(shí)很少接觸)
- TAP 基于任務(wù)的異步編程模式
C# 5.0
C# 5.0的主旨很明確,就是圍繞異步編程進(jìn)行的足陨。我在寫(xiě)前面版本特性時(shí)特地把異步編程的演變放在里面嫂粟,就是想體現(xiàn)對(duì)于異步編程這個(gè)主題在時(shí)間線上的演變過(guò)程,它的三次演變(反別在1.x墨缘、2.0和4.0)最終在C#中合并為async和await兩個(gè)極其簡(jiǎn)單的語(yǔ)法糖來(lái)實(shí)現(xiàn)赋元。這個(gè)版本提供的特性:
- 基于TPL(任務(wù)運(yùn)行庫(kù))的異步編程,async和await關(guān)鍵字封裝了大量的代碼(從IL來(lái)看它們就只是語(yǔ)法糖)飒房,極大地簡(jiǎn)化了異步編程的過(guò)程搁凸,是用同步的思想實(shí)現(xiàn)異步編程的最好體現(xiàn)。
- foreach循環(huán)中捕獲變量修正狠毯,解決了閉包導(dǎo)致的變量捕獲問(wèn)題(js中還得用匿名函數(shù)等等方法來(lái)解決护糖,C#直接從編譯器層面給它改了)
string[] items = { "x","y","z" };
var actions = new List<action>();
foreach(string item in items)
{
actions.add(()=>Console.WriteLine(item)); //輸出“xyz”,之前版本是“zzz”
}
- 調(diào)用者信息特性(從沒(méi)用到過(guò)的三個(gè)Attribute)
C# 6.0
書(shū)中沒(méi)有涉及到C# 6.0的語(yǔ)言特性,下面的內(nèi)容是根據(jù)網(wǎng)上的資料整理的
- 自動(dòng)屬性初始化器
public string Name { get; set; } = "Tom";
Lambda表達(dá)式可以用作方法體或?qū)傩?/p>
字典初始化器嚼松,初始化器終于支持字典類型了
var dic = new Dictionary<string, string>()
{
["name"] = "Tom",
["gender"] = "male"
};
使用Using Static引用靜態(tài)類嫡良,調(diào)用時(shí)可省略類名
catch 塊中可以使用 await關(guān)鍵字了
異常過(guò)濾器
try
{
...
}
catch (Exception ex) if (ex.InnerException == null)
{
...
}
- 新運(yùn)算符“?.”献酗,檢查對(duì)象是否為null寝受,以此決定后續(xù)操作
list?.Count; //list不為null則返回屬性Count,否則返回null
- 字符串嵌入,即簡(jiǎn)化的string.Format形式
var tom = new { Name="Tom",Age=10 };
Console.WriteLine($"Age:{tom.Age} Name:{tom.Name}");
nameof表達(dá)式罕偎,直接獲得變量很澄、方法、對(duì)象名
無(wú)參數(shù)的結(jié)構(gòu)體構(gòu)造函數(shù)
C# 7.0
C# 7.0推出還不算太久颜及,和上個(gè)版本一樣甩苛,并沒(méi)有太亮眼的特性。此部分的內(nèi)容參考這篇文章[干貨來(lái)襲]C#7.0新特性(VS2017可用)
out變量可以在使用時(shí)直接申明
增強(qiáng)的數(shù)據(jù)類型元組 * Tuples * (真成大雜燴了)
匹配模式
增強(qiáng)的ref關(guān)鍵字俏站,可用于局部變量和return
局部函數(shù)(這.............讯蒲,我有點(diǎn)看不懂了)
構(gòu)造函數(shù),析構(gòu)函數(shù),和屬性訪問(wèn)器現(xiàn)在也能用表達(dá)式了
throw關(guān)鍵詞可用于表達(dá)式了
通用的異步返回類型ValueTask<T>,原來(lái)的void肄扎,Task 或 Task<T>可以被同義替換
允許數(shù)字中出現(xiàn)"_"這個(gè)分割符號(hào)墨林,值不變赁酝,只是提高可讀性(這.............)