轉自: http://blog.csdn.net/wulex/article/details/73499500html
之因此在這裏分享這個對應關係,是由於在C#基礎知識系列的文章發佈以後,有些初學者對.NET版本和C#語言特性之間的對應關係有點不清楚,有時候會弄混淆了。web
而且經過這個對應關係,也能夠幫助你們對C#和.NET 類庫有個全面的把控,能夠幫助你們理清楚C#和.NET 類庫中各個知識點,使他們能夠對號入坐。具體他們的之間對應關係見下表:編程
版本 | .NET Framework版本 | Visual Studio版本 | 發佈日期 | 特性 |
---|---|---|---|---|
C# 1.0 | .NET Framework 1.0 | Visual Studio .NET 2002 | 2002.1 | 委託 |
事件 | ||||
C# 1.1 | .NET Framework 1.1 | Visual Studio .NET 2003 | 2003.4 | APM |
C# 2.0 | .NET Framework 2.0 | Visual Studio 2005(開始命名爲Visual Studio) | 2005.11 | 泛型 |
匿名方法 | ||||
迭代器 | ||||
可空類型 | ||||
C# 3.0 | .NET Framework 3.0 | Visual Studio 2008 | 2007.11 | 隱式類型的部變量 |
.NET Framework 3.5 | 對象集合初始化 | |||
自動實現屬性 | ||||
匿名類型 | ||||
擴展方法 | ||||
查詢表達式 | ||||
Lambda表達式 | ||||
表達式樹 | ||||
分部類和方法 | ||||
Linq | ||||
C# 4.0 | .NET Framework 4.0 | Visual Studio 2010 | 2010.4 | 動態綁定 |
命名和可選參數 | ||||
泛型的協變和逆變 | ||||
互操做性 | ||||
C# 5.0 | .NET Framework 4.5 | Visual Studio 2012 | 2012.8 | 異步和等待(async和await) |
調用方信息(Caller Information) |
C# 5.0隨着VisualStudio 2012一塊兒正式發佈了,讓咱們來看看C#5.0中增長了哪些功能。c#
在.Net 4.5中,經過async和await兩個關鍵字,引入了一種新的基於任務的異步編程模型(TAP)。在這種方式下,能夠經過相似同步方式編寫異步代碼,極大簡化了異步編程模型。以下式一個簡單的實例:架構
static async void DownloadStringAsync2(Uri uri) { var webClient = new WebClient(); var result = await webClient.DownloadStringTaskAsync(uri); Console.WriteLine(result); }
而以前的方式是這樣的:app
static void DownloadStringAsync(Uri uri) { var webClient = new WebClient(); webClient.DownloadStringCompleted += (s, e) => { Console.WriteLine(e.Result); }; webClient.DownloadStringAsync(uri); }
也許前面這個例子不足以體現async和await帶來的優越性,下面這個例子就明顯多了:框架
public void CopyToAsyncTheHardWay(Stream source, Stream destination) { byte[] buffer = new byte[0x1000]; Action<IAsyncResult> readWriteLoop = null; readWriteLoop = iar => { for (bool isRead = (iar == null); ; isRead = !isRead) { switch (isRead) { case true: iar = source.BeginRead(buffer, 0, buffer.Length, readResult => { if (readResult.CompletedSynchronously) return; readWriteLoop(readResult); }, null); if (!iar.CompletedSynchronously) return; break; case false: int numRead = source.EndRead(iar); if (numRead == 0) { return; } iar = destination.BeginWrite(buffer, 0, numRead, writeResult => { if (writeResult.CompletedSynchronously) return; destination.EndWrite(writeResult); readWriteLoop(null); }, null); if (!iar.CompletedSynchronously) return; destination.EndWrite(iar); break; } } }; readWriteLoop(null); } public async Task CopyToAsync(Stream source, Stream destination) { byte[] buffer = new byte[0x1000]; int numRead; while ((numRead = await source.ReadAsync(buffer, 0, buffer.Length)) != 0) { await destination.WriteAsync(buffer, 0, numRead); } }
關於基於任務的異步編程模型須要介紹的地方還比較多,不是一兩句能說完的,有空的話後面再專門寫篇文章來詳細介紹下。另外也可參看微軟的官方網站:Visual Studio Asynchronous Programming,其官方文檔Task-Based Asynchronous Pattern Overview介紹的很是詳細, VisualStudio中自帶的CSharp Language Specification中也有一些說明。異步
不少時候,咱們須要在運行過程當中記錄一些調測的日誌信息,以下所示:async
public void DoProcessing() { TraceMessage("Something happened."); }
爲了調測方便,除了事件信息外,咱們每每還須要知道發生該事件的代碼位置以及調用棧信息。在C++中,咱們能夠經過定義一個宏,而後再宏中經過FILE和LINE來獲取當前代碼的位置,但C#並不支持宏,每每只能經過StackTrace來實現這一功能,但StackTrace卻有不是很靠譜,經常獲取不了咱們所要的結果。異步編程
針對這個問題,在.Net 4.5中引入了三個Attribute:CallerMemberName
、CallerFilePath
和CallerLineNumber
。在編譯器的配合下,分別能夠獲取到調用函數(準確講應該是成員)名稱,調用文件及調用行號。上面的TraceMessage函數能夠實現以下:
public void TraceMessage(string message, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0) { Trace.WriteLine("message: " + message); Trace.WriteLine("member name: " + memberName); Trace.WriteLine("source file path: " + sourceFilePath); Trace.WriteLine("source line number: " + sourceLineNumber); }
另外,在構造函數,析構函數、屬性等特殊的地方調用CallerMemberName屬性所標記的函數時,獲取的值有所不一樣,其取值以下表所示:
調用的地方 | CallerMemberName獲取的結果 |
---|---|
方法、屬性或事件 | 方法,屬性或事件的名稱 |
構造函數 | 字符串 「.ctor」 |
靜態構造函數 | 字符串 「.cctor」 |
析構函數 | 該字符串 「Finalize」 |
用戶定義的運算符或轉換 | 生成的名稱成員,例如, 「op_Addition」。 |
特性構造函數 | 特性所應用的成員的名稱 |
例如,對於在屬性中調用CallerMemberName
所標記的函數便可獲取屬性名稱,經過這種方式能夠簡化 INotifyPropertyChanged 接口的實現。關於調用方信息更詳細的資料,請參看MSDN:http://msdn.microsoft.com/zh-cn/library/hh534540.aspx。
這個只是簡化了數據綁定,跟ASP.NET MVC3不斷改進同樣,其實不是什麼亮點改進。
comboBox1.Text :=: textBox1.Text; //將文本框的內容綁定到下拉框。
這個的加入給一些設計增長了強大功能,泛型早在C#2.0加入後就有着強大的應用,通常稍微設計比較好的框架,都會用到泛型,c#5.0加入帶參數泛型構造函數,則在原有基礎上對C#泛型完善了不少。:)
public class T MyClass : T: class, new() public class T MyClass : T:class, new(int)
此功能,我的以爲並不是什麼大的亮點,但至少對null類型,特別是有數據計算的這種null類型的支持,寫代碼仍是方便很多。
注意對於Nullable Types,在C#2.0就加入進來了,可是不支持計算,好比:
int? x = null;
int? y = x + 40;
那麼y值是多少?不支持計算,獲得的是null,想必你們知道爲何結果是null了吧?但C#5.0能夠,40加一個null的整數,咱們要的結果是40,不過份吧?
int x? = null; int y? = x + 40; Myobject obj = null; Myotherobj obj2 = obj.MyProperty ??? new Myotherobj();
這個是一個我很早就想若是能這樣就行了,沒想到在C#5.0裏就加入此功能,之前case裏只能寫一個具體的常量,而如今能夠加表達式了,靈活多了。
switch(myobj){ llorEmpty(myotherobj): //邏輯代碼 case myotherobj.Trim().Lower: //邏輯代碼 }
咱們在C#3.0裏有擴展方法,那麼在C#5.0裏將會加入擴展屬性的感念,對照擴展方法,不難理解擴展屬性的概念了。如下爲擴展屬性的定義舉例:
[Associate(string)]
public static int Zivsoft_ExtensionProperty { get;set;}
C#5.0 遠遠不僅是上面描述的5點新功能,它如同C#4.0加入dynamic概念同樣,會加入異步處理概念,這個不是幾行代碼就能表達,而是將在設計,架構上,又會掀起一次飛躍……
爲了你們搶先看,就給一段C#5.0一段簡單的異步操做的代碼例子,注意(C#5.0兩個新加的關鍵字async, await):
Task<Movie> GetMovieAsync(string title); Task PlayMovieAsync(Movie movie); async void GetAndPlayMoviesAsync(string[] titles) { foreach (var title in titles) { var movie = await GetMovieAsync(title); await PlayMovieAsync(movie); } }