回顾C#各版本特性

时间:2022-04-20 04:51:09

Read-only auto-properties(只读自动属性)

以前版本,声明只读属性时,示例:

public string FirstName { get; private set; } public string LastName { get; private set; }

6.0,不显示写setter即是只读属性,但属性也只能在构造函数中初始化了

示例:

public string FirstName { get; } public string LastName { get; }

Auto-Property Initializers(自动属性初始化)

以前版本,属性的初始化需要放在构造函数中进行,6.0可以在属性声明时初始化

示例:

public ICollection<double> Grades { get; } = new List<double>(); public Standing YearInSchool { get; set;} = Standing.Freshman;

Expression-bodied function members(表达式体函数成员)

6.0可以直接在函数体使用表达式,这简化一些很简单的函数的书写(仅支持使用只读的属性)

示例:

public override string ToString() => $"{LastName}, {FirstName}"; public string FullName => $"{FirstName} {LastName}";

using static

可以直接引用具体对象,然后在本地直接使用其静态函数。

以前:

using System; namespace TestCsharp { class Program { static void Main(string[] args) { Console.WriteLine("ok"); } } }

6.0版本:

using static System.Console; namespace TestCsharp { class Program { static void Main(string[] args) { WriteLine("ok"); } } }

 Null-conditional operators(空条件操作符)

更加简化的空对象判断,不为空可直接访问其属性

以前先判断对象不为空,再访问属性:

class Program { static void Main(string[] args) { Person person = new Person(); var first = person == null ? "" : person.FirstName; Console.WriteLine(first); } } class Person { public string FirstName { get; set; } public Person() { FirstName = "init name"; } }

  

6.0版本,直接替换属性访问 . 为 ?. 一步完成判断和访问:

class Program { static void Main(string[] args) { Person person = new Person(); var first = person?.FirstName; Console.WriteLine(first); } } class Person { public string FirstName { get; set; } public Person() { FirstName = "init name"; } }

String interpolation(字符串插值)

以前,字符串拼接时,要使用string.Format,示例:

public string FullName { get { return string.Format("Name is{0} {1}", FirstName, LastName); } }

6.0可以直接使用$代替string.Format,示例:

public string FullName { get { return $"Name is {FirstName}{LastName}"; } }

 进一步,可以在其中使用 : 标示格式化风格,如下,F2标识两位小数,示例:

public string GetGradePointPercentage() => $"Name: {LastName}, {FirstName}. G.P.A: {Grades.Average():F2}";

Exception Filters(异常过滤器)

增加过滤器,直接在异常捕获后就可以进行相应的判断

以前:

public static async Task<string> MakeRequest() { var client = new System.Net.Http.HttpClient(); var streamTask = client.GetStringAsync("https://localHost:10000"); try { var responseText = await streamTask; return responseText; } catch (System.Net.Http.HttpRequestException e) { if (e.Message.Contains("301")) return "Site Moved"; else throw; } }

6.0版本,在外部使用when进行条件匹配:

public static async Task<string> MakeRequest() { var client = new System.Net.Http.HttpClient(); var streamTask = client.GetStringAsync("https://localHost:10000"); try { var responseText = await streamTask; return responseText; } catch (System.Net.Http.HttpRequestException e) when (e.Message.Contains("301")) { return "Site Moved"; } }

nameof Expressions

主要场景是异常中提供名字:

if (IsNullOrWhiteSpace(lastName)) throw new ArgumentException(message: "Cannot be blank", paramName: nameof(lastName));

  还有就是MVVM中INotifyPropertyChanged实现:

public string LastName { get { return lastName; } set { if (value != lastName) { lastName = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(LastName))); } } } private string lastName;

Await in Catch and Finally blocks

版本5中对await的使用做了一些限制,6中去除了这些限制。

示例:

public static async Task<string> MakeRequestAndLogFailures() { await logMethodEntrance(); var client = new System.Net.Http.HttpClient(); var streamTask = client.GetStringAsync("https://localHost:10000"); try { var responseText = await streamTask; return responseText; } catch (System.Net.Http.HttpRequestException e) when (e.Message.Contains("301")) { await logError("Recovered from redirect", e); return "Site Moved"; } finally { await logMethodExit(); client.Dispose(); } }

Index Initializers

之前版本示例:

private List<string> messages = new List<string> { "Page not Found", "Page moved, but left a forwarding address.", "The web server can‘t come out to play today." };

6.0版本: