Below you will find pages that utilize the taxonomy term “CSharp 6.0”
Posts
C# 6.0 - Await in catch/finally
C# 6.0 以前 await 無法用在 catch/finally 區塊,C# 6.0 後開始支援。
using System; using System.Threading.Tasks; namespace ConsoleApplication10 { class Program { static void Main(string[] args) { Test(); System.Threading.Thread.Sleep(10000); } private static async void Test() { try { throw new Exception(); } catch { Console.WriteLine("Catch..."); await Task.Delay(500); } finally { Console.WriteLine("Finally..."); await Task.Delay(500); } } } }
read morePosts
C# 6.0 - Extension Add methods in collection initializers
C# 6.0 以前,集合類別可以像下面這樣透過 Collection Initializers 初始集合成員:
... var blogs = new List< Blog> { new Blog( "Level Up 1", "http://www.dotblogs.com.tw/larrynung" ), new Blog( "Level Up 2", "http://larrynung.github.io" ) }; ... {% endcodeblock%} <br/> 但無法像 VB 10 以後的版本一樣透過擴充方法客製處理 Collection Initializers 的動作,一直到 C# 6.0 才被加入 C# 內。 <br/> 只要為集合撰寫 Add 擴充方法即可客製處理 Collection Initializers,像是如果預期要讓 List<Blog> 的初始可以直接帶入 name 與 url,就會像下面這樣撰寫: ```c# ... public static class BlogExtension { public static void Add(this List<Blog> list, string name, string url) { list.
read morePosts
C# 6.0 - Parameterless constructors in structs
在 C# 6.0 以前,Struct 會自帶 Parameterless Constructors,且不允許我們自行實作,像是下面這樣的程式碼:
... public Blog() : this( string.Empty, string.Empty) { Console.WriteLine( "Blog.Ctor()..."); } public Blog(string name, string url) { this.Name = name; this.Url = url; } ... 運行在 C# 6.0 以前,編譯器就會告知錯誤:
{% img /images/posts/ParamlessStructConstructor/1.png %}
如果想要在 Parameterless Constructors 自行加些處理,像是用建構子鏈導到別的建構子去建構,在 C# 6.0 以前都沒辦法。
在 C# 6.0 以後,就比較沒有這樣的限制了,我們可以自行撰寫自己的 Paramless Constructor,加上自己想要的處理動作。唯一要注意的是需要透過 new 語法建立的才會觸發自己撰寫的 Paramless Constructor。
... var blog = default( Blog); DumpBlog(blog); blog = new Blog() { Name = "Larry Nung", Url = "http://larrynung.
read morePosts
C# 6.0 - Index initializers
以往我們在撰寫 C#,有 Object Initializer 與 Collection Initializer 可輔助我們作初始的動作,雖然可以初始大多數的資料,但在 Index 與 Event 這邊卻無法直接初始。
如果以 Dictionary 來說,因為他還是屬於集合的一種,所以仍舊可以像下面這樣透過 Collection Initializer 在初始的同時就將內容一併放入:
... var blog1 = new Dictionary<string , string >() { { "Name", "Level Up" }, { "Url", "http://larrynung.github.io/index.html" } }; ... 但並不是所有的情況下都可以用 Collection Initializer 來做 Index 的初始,所以在 C# 6.0 導入了 Index initializers,寫起來會像下面這樣,就像透過索引子塞值一般:
... var blog = new Dictionary<string , string >() { [ "Name"] = "Level Up" , [ "Url"] = "http://larrynung.github.io/index.html" }; .
read morePosts
C# 6.0 - String interpolation
以往在做比較簡單的字串串接,我們可能會用 + 運算符號進行串接,或是用 String.Format 帶入 Pattern 與要串接的字串去處理,像是下面這樣:
... Console.WriteLine((++idx).ToString("D2") + ". " + blog.Name + " (" + blog.Url + ")"); Console.WriteLine( String.Format( "{0:D2}. {1} ({2})", ++idx, blog.Name, blog.Url)); ... 在 C# 6.0 導入了 String Interpolation,可以像下面這樣簡化寫法:
... Console.WriteLine( "\{++idx, 5 :D2 }. \{blog.Name } (\{blog.Url ?? String.Empty})" ); ... 有點像是本來 String.Format 的 Pattern 內直接用斜線與大括號包住帶入運算式,且支援 optional alignment 與 format specifiers 的設定。
這邊來看個完整的使用範例:
using System; using System.Collections.Generic; public class Program { static void Main(string[] args) { var blog = new Blog { Name = "Level Up", Url = "http://larrynung.
read morePosts
C# 6.0 - Expression bodied members
Expression bodied members 是預計要在 C# 6.0 釋出的新功能,目前已可在 Visual Studio 14 中透過設定將功能開啟進行體驗,只要在方案檔中加上:
<LangVersion>experimental</LangVersion> 當撰寫簡單的成員方法或是屬性時,Expression bodied members 能讓我們將程式碼精簡。
在使用上就只要將屬性或方法的宣告後面直接接上 Lambda 表示式即可。
像是成員屬性的處理會像下面這樣,少了本來大括弧的區塊,也少了 Get 區塊。
... public string ID => Guid.NewGuid().ToString(); ... 如果是成員方法處理上也類似,只是本來大括弧區塊內的內容用 Lambda 取代。
... public override string ToString() => this.Name; ... 這邊可以看到用這樣的寫法可能會造成很難區別是屬性還是方法,使用上要特別注意小心,基本上差異只在於後面有沒有接小括弧區塊及方法的參數。
最後看個完整的範例:
using System; public class Program(string name) { public string ID => Guid.NewGuid().ToString(); public string Name { get; private set ; } = name; public override string ToString() => this.
read morePosts
C# 6.0 - Nameof expressions
Nameof expressions 是預計要在 C# 6.0 釋出的新功能,目前已可在 Visual Studio 14 CTP3 中透過設定將功能開啟進行體驗,只要在方案檔中加上:
<LangVersion>experimental</LangVersion> Nameof expressions 能讓開發人員輕易的在程式中取得變數或是類別名稱。
以往我們是無法取得變數名稱的,所以像是在撰寫參數檢查,當丟出的例外需要帶入參數名稱時,多半是自己填入字串帶入。但這樣的做法不是很恰當,因為拼錯時並不容易發現,且當重構參數名稱時很容易遺漏要配合修改。
至於類別名稱的取得,相較於變數名稱的取得是簡單了許多。但是名稱的取得需要 Runtime 進行解析,這樣的做法有時又多了一些無謂的耗費。
Nameof expressions 的出現能幫助開發人員解決這樣的問題,使用上只要叫用nameof,並帶入欲取得名稱的類別或變數即可。
nameof( 欲取得名稱的類別或變數 ) 這邊直接看個完整的使用範例:
using System; namespace ConsoleApplication10 { class Program { static void Main(string[] args) { var blog = new Blog { Name = "Level Up" , Url = "http://larrynung.github.io/" }; DumpBlogInfo(blog); DumpBlogInfo(null); } static void DumpBlogInfo(Blog blog) { Console.WriteLine( string.Format( "Dump data (Type is {0})..." , nameof(Blog ))); if (blog == null) throw new ArgumentNullException(nameof (blog)); Console.
read morePosts
C# 6.0 - Null propagation
— layout: post title: “C# 6.0 - Null propagation” date: 2014-08-21 00:03:00 comments: true tags: [CSharp, CSharp 6.0] keywords: “C#” description: “C# 6.0 - Null propagation”
read morePosts
C# 6.0 - Exception filters
Exception filters 是預計要在 C# 6.0 釋出的新功能,目前已可在 Visual Studio 14 中透過設定將功能開啟進行體驗,只要在方案檔中加上:
<LangVersion>experimental</LangVersion> 或是透過 .Net Fiddle 也可以,Compiler 那邊選取 Roslyn 就可以了。
Exception filters 能讓開發人員很容易的在攔截例外時順帶做些過濾的動作,藉此處理符合過濾條件的例外,且不對例外呼叫堆疊造成不良的影響。
以往我們必須要先將例外攔截,接著進行比對過濾,最後將符合的例外做對應的處理,不符合的例外繼續讓它向外擴出。但是這樣的作法會讓例外呼叫堆疊看不到實際發生的例外點,只看到重新擴出例外的點,造成除錯上的困難。
{% img /images/posts/ExceptionFilters/1.png %}
Exception filters 的出現能幫助開發人員解決這樣的問題。
它的語法很直覺,簡單來說就只是在 Try/Catch 的 Catch 後面加上 if 條件式進行過濾。
try {...} catch(Exception e) if (...) {...} 程式寫起來會像下面這樣:
反組譯看一下,可以看到 Exception filters 這邊會被編譯成 filter 區塊的部份,從 IL 這邊就直接支援。
{% img /images/posts/ExceptionFilters/2.png %}
這樣的寫法不僅直覺,且不會對例外呼叫堆疊造成不良的影響。
{% img /images/posts/ExceptionFilters/3.png %}
最後這邊做個新舊方法的測試比較:
可以看到效能的部份其實是差不多的,新語法感覺是沒有任何的效能優化。
read morePosts
C# 6.0 - Using static members
Using static members 是預計要在 C# 6.0 釋出的新功能,目前已可在 Visual Studio 14 中透過設定將功能開啟進行體驗,只要在方案檔中加上:
<LangVersion>experimental</LangVersion> 或是透過 .Net Fiddle 也可以,Compiler 那邊選取 Roslyn 就可以了。
Using static members 能讓開發人員更方便的對指定類別的靜態成員做存取。對於程式中有大量的靜態成員存取操作時特別好用。
使用上與 Namespace 的 Using 類似,只是後面帶的不是到 Namespace 而已,而是進一步再向下帶到 Class。用 Using 指定要存取的類別後,在程式中就可以直接存取該類別的靜態成員,就如同自身的成員一般。
以一個較完整的例子來看,程式寫起來會像下面這樣:
可以看到這邊程式的一開始就先使用 Using 引用 Console 類別,後續我們就可以在程式中直接存取 Console 類別的靜態成員,像是取用 Title 、或是呼叫 WriteLine 方法。
反組譯看一下,可以發現其實該語法也只是編譯器幫我們在編譯時做了些處理。
{% img /images/posts/UsingStaticMembers/1.png %}
read morePosts
C# 6.0 - Auto-property initializers
Auto-property initializers 是預計要在 C# 6.0 釋出的新功能,目前已可在 Visual Studio 14 中透過設定將功能開啟進行體驗,只要在方案檔中加上:
<LangVersion>experimental</LangVersion> 或是透過 .Net Fiddle 也可以,Compiler 那邊選取 Roslyn 就可以了。
Auto-property initializers 能讓開發人員在宣告 Auto-property 的同時就順道做初始的動作。不用另行在建構子中設定。也不再寫用回一般的 Property 寫法,然後在 Field 宣告時設定。
它的語法很直覺,簡單來說就是本來的 Auto-property 後面直接接上賦值的語法。像是:
public string Property { get; set; } = "Value"; 除了一般可讀可寫的 Property 外,唯讀的甚至是靜態的 Property 該語法也都支援。
以一個較完整的例子來看,程式寫起來會像下面這樣:
程式寫起來可以看到比以往精簡許多,運行後屬性也都有正確的賦值。
反組譯看一下,可以看到比較接近透過變數初始器去做賦值的動作,會在基底類別初始前宣告,也會標注 beforefieldinit。
{% img /images/posts/AutoPropertyInitializers/1.png %}
{% img /images/posts/AutoPropertyInitializers/2.png %}
read more