背水一戰 Windows 10 (43) - C# 7.0 新特性
作者:webabcd
介紹
背水一戰 Windows 10 之 C# 7.0 新特性
- 介紹 C# 7.0 的新特性
示例
1、C# 7.0 示例 1: out 變量, 數字語法改進, 值類型的異步返回
CSharp7/Demo1.xaml.cs
/* * C# 7 示例 1 * out 變量, 數字語法改進, 值類型的異步返回 */ using System; using System.Threading.Tasks; using Windows.UI.Xaml.Controls; namespace Windows10.CSharp7 { public sealed partial class Demo1 : Page { public Demo1() { this.InitializeComponent(); sample1(); sample2(); sample3(); } // out 變量(out-variables) private void sample1() { // 這是之前的寫法,需要預先聲明變量 string s; OutSample(out s); lblMsg.Text += s; lblMsg.Text += Environment.NewLine; // 這是 c#7 的寫法,不用預先聲明變量了 OutSample(out string ss); lblMsg.Text += ss; lblMsg.Text += Environment.NewLine; // 這是 c#7 的寫法,不用預先聲明變量了,並且可以使用 var OutSample(out var sss); lblMsg.Text += sss; lblMsg.Text += Environment.NewLine; } private void OutSample(out string str) { str = "xyz"; /* * 注: * 1、對於 out 類型來說,是在方法內部初始化的,在 c#7 之前需要在方法外部聲明(這顯得沒有必要,所以有了如今的改進) * 2、對於 ref 類型來說,是不可能改成 out 這種新方式的,因為 ref 是引用,其作用是方法外部初始化,方法內部改之 */ } // 數字語法改進(numeric literal syntax improvements) private void sample2() { int a1 = 123456; int a2 = 123_456; // 允許數字中出現“_”來提高可讀性 lblMsg.Text += a1.ToString(); lblMsg.Text += Environment.NewLine; lblMsg.Text += a2.ToString(); lblMsg.Text += Environment.NewLine; int b1 = 0xABCDEF; int b2 = 0xAB_CD_EF; // 允許數字中出現“_”來提高可讀性 lblMsg.Text += b1.ToString(); lblMsg.Text += Environment.NewLine; lblMsg.Text += b2.ToString(); lblMsg.Text += Environment.NewLine; } // 值類型的異步返回(generalized async return types) private async void sample3() { lblMsg.Text += (await GetNumber1()).ToString(); lblMsg.Text += Environment.NewLine; lblMsg.Text += (await GetNumber2()).ToString(); lblMsg.Text += Environment.NewLine; } // 在 c#7 之前異步返回 int 是這么寫的,Task 是引用類型 private async Task<int> GetNumber1() { await Task.Delay(100); return 1; } // 在 c#7 中異步返回 int 可以這么寫,ValueTask 是值類型,提高了效率 // 注:需要通過 nuget 引用 System.Threading.Tasks.Extensions private async ValueTask<int> GetNumber2() { await Task.Delay(100); return 1; } } }
2、C# 7.0 示例 2: 值類型變量的引用和值類型返回值的引用, 模式匹配, 元組
CSharp7/Demo2.xaml.cs
/* * C# 7 示例 2 * 值類型變量的引用和值類型返回值的引用, 模式匹配, 元組 */ using System; using Windows.UI.Xaml.Controls; namespace Windows10.CSharp7 { public sealed partial class Demo2 : Page { public Demo2() { this.InitializeComponent(); sample1(); sample2(); sample3(); } // 值類型變量的引用和值類型返回值的引用(ref locals and returns) private void sample1() { // 值類型變量變為引用類型的示例 int a = 1; ref int b = ref a; // 值類型變量 b 引用了值類型變量 a a = 2; lblMsg.Text = a.ToString(); lblMsg.Text += Environment.NewLine; // 值類型返回值變為引用類型的示例 int[] array = { 1, 2, 3, 4, 5 }; ref int x = ref GetByIndex(array, 2); // 值類型變量 x 引用了 GetByIndex(array, 2) x = 99; lblMsg.Text += array[2].ToString(); lblMsg.Text += Environment.NewLine; } // 返回的值類型變為引用類型 private ref int GetByIndex(int[] array, int index) { return ref array[index]; } // 模式匹配(pattern matching) private void sample2() { object a = 1; // 聲明 int b,如果 a 是 int 類型則將 a 賦值給 b if (a is int b) { lblMsg.Text += b.ToString(); lblMsg.Text += Environment.NewLine; } switch (a) { // 聲明 int c,如果 a 是 int 類型則將 a 賦值給 c,如果 c 大於 0 則執行此 case case int c when c > 0: lblMsg.Text += "case int c when c > 0: " + c; lblMsg.Text += Environment.NewLine; break; // 聲明 string c,如果 a 是 string 類型則將 a 賦值給 c case string c: lblMsg.Text += "case string c: " + c; lblMsg.Text += Environment.NewLine; break; } } // 元組(Tuples) // 注:需要通過 nuget 引用 System.ValueTuple private void sample3() { // Tuples 特性是從 System.Tuple<T1, T2, T3...> 進化而來的 // 注:當有多個返回值時,使用 Tuples 特性是非常方便的 var user1 = GetUser1(); lblMsg.Text += $"{user1.UserId}, {user1.UserName}, {user1.CreateTime}"; lblMsg.Text += Environment.NewLine; var user2 = GetUser2(); lblMsg.Text += $"{user2.UserId}, {user2.UserName}, {user2.CreateTime}"; lblMsg.Text += Environment.NewLine; var user3 = GetUser3(); lblMsg.Text += $"{user3.Item1}, {user3.Item2}, {user3.Item3}"; lblMsg.Text += Environment.NewLine; (int UserId, string UserName, DateTime CreateTime) = GetUser1(); lblMsg.Text += $"{UserId}, {UserName}, {CreateTime}"; lblMsg.Text += Environment.NewLine; var obj1 = (UserId: 1, UserName: "webabcd"); lblMsg.Text += $"{obj1.UserId}, {obj1.UserName}"; lblMsg.Text += Environment.NewLine; var obj2 = (1, "webabcd"); lblMsg.Text += $"{obj2.Item1}, {obj2.Item2}"; lblMsg.Text += Environment.NewLine; (int id, string name) = (1, "webabcd"); lblMsg.Text += $"{id}, {name}"; lblMsg.Text += Environment.NewLine; } private (int UserId, string UserName, DateTime CreateTime) GetUser1() { return (1, "webabcd", DateTime.Now); } private (int UserId, string UserName, DateTime CreateTime) GetUser2() { return (UserId: 1, UserName: "webabcd", CreateTime: DateTime.Now); } private (int, string, DateTime) GetUser3() { return (1, "webabcd", DateTime.Now); } } }
3、C# 7.0 示例 3: 表達式拋出異常, lambda 表達式作用於構造函數或屬性, 局部函數
CSharp7/Demo3.xaml.cs
/* * C# 7 示例 3 * 表達式拋出異常, lambda 表達式作用於構造函數或屬性, 局部函數 */ using System; using Windows.UI.Xaml.Controls; namespace Windows10.CSharp7 { public sealed partial class Demo3 : Page { public Demo3() { this.InitializeComponent(); sample1(); sample2(); sample3(); } // 表達式拋出異常(throw expressions) private void sample1() { try { string a = null; // 支持在表達式中拋出異常 string b = a ?? throw new Exception("ex"); } catch (Exception ex) { lblMsg.Text += ex.ToString(); lblMsg.Text += Environment.NewLine; } } // lambda 表達式作用於構造函數或屬性(more expression-bodied members) // 注:在 c#6 中已經支持了 lambda 表達式作用於字段或方法 private void sample2() { MyClass obj = new MyClass("webabcd"); lblMsg.Text += obj.Text; lblMsg.Text += Environment.NewLine; } public class MyClass { private string _text; public MyClass(string text) => _text = text; // lambda 表達式作用於構造函數 public string Text // lambda 表達式作用於屬性 { get => _text; set => _text = value ?? "default text"; } } // 局部函數(local functions) private void sample3() { int a = GetNumber(); lblMsg.Text += a.ToString(); lblMsg.Text += Environment.NewLine; // 支持局部函數了 int GetNumber() { return 1; } } } }
OK
[源碼下載]