C# 二十年語法變遷之 C# 5 和 C# 6參考

C# 二十年語法變遷之 C# 5 和 C# 6參考

https://benbowen.blog/post/two_decades_of_csharp_ii/

自從 C# 于 2000 年推出以來,該語言的規模已經大大增加,我不確定任何人是否有可能在任何時候都對每一種語言特性都有深入的了解。因此,我想寫一系列快速參考文章,總結自 C# 2.0 以來所有主要的新語言特性。我不會詳細介紹它們中的任何一個,但我希望這個系列可以作為我自己(希望你也是!)的參考,我可以不時回過頭來記住我使用的工具工具箱里有。:)

開始之前的一個小提示:我將跳過一些更基本的東西(例如 C# 2.0 引入了泛型,但它們的使用范圍如此廣泛,以至于它們不值得包括在內);而且我還可以將一些功能“粘合”在一起,以使其更簡潔。本系列并不打算成為該語言的權威或歷史記錄。相反,它更像是可能派上用場的重要語言功能的“備忘單”。

C# 5.0

Async/await

此功能是 C# 的支柱,對行業產生了如此大的影響,以至于它已進入其他主流語言。有無數的教程和書籍深入到這個特性;但這篇文章只是作為一個快速參考指南,所以我只在這里總結一下。

Async/await 允許方法使用異步但以同步方式編寫:

// async keyword tells the compiler we're writing an async method
// Task<int> is a 'Future'/Promise that will eventually yield a value of type int
async Task<int> GetUserAgeFromDatabase(string username) {// await keyword tells the compiler to convert this method in to a state machine at this point// Method will return the Task<int> immediately at this point (assuming GetUserDetails() does not complete immediately and synchronously)// A continuation for the remainder of the method will be scheduled either on this thread (via captured context) or on task pool thread (by default) to be executed once GetUserDetails()'s Task has completedvar userDetails = await _databaseAccessLayer.GetUserDetails(username);// Once we're here, we're executing the continuationreturn userDetails.Age;
}

Caller Info 屬性

此功能涉及可應用于可選方法參數的三個屬性。然后編譯器將填寫詳細信息;這些主要用于記錄:

static void Log(string message, [CallerMemberName] string callerMemberName = null, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNumber) {Console.WriteLine($"{message} (called from {callerMemberName} on line {callerLineNumber} in file {callerFilePath})");
}static void Test() {Log("My message"); // Will print something like "My message (called from Test() on line 15 in file C:\...\Example.cs)"
}

? “Caller Info 屬性”

C# 6.0

靜態導入Static Imports

此功能允許在不使用類名的情況下在類上使用靜態方法:

using static System.Console;static void Test() {WriteLine("hello"); // No Console. prefix required
}

? “靜態導入”

異常過濾器

異常過濾器僅在滿足某些參數時才允許捕獲異常:

static void Test() {try {SomeOperation();}catch (Exception e) when (e.InnerException is OperationCanceledException oce) {Console.WriteLine($"Operation was cancelled: {oce}");}
}

? “異常過濾器”

不可變的自動屬性

此功能允許從自動屬性中省略設置器以使其不可變:

class MyClass {public string Name { get; }public MyClass(string name) {Name = name; // Can be initialized in constructor}
}

? “Immutable Auto-Properties” 名稱不能從構造函數以外的任何地方設置(或內聯,請參閱下一個功能)。

自動屬性初始化器

這允許在其聲明點為內聯屬性設置初始值:

class MyClass {public string Name { get; } = "Ben";public int Age { get; set; } = 30;
}

? “自動屬性初始化程序”

表達體成員

此功能允許將某些函數體編寫為單行表達式:

class MyClass {// Age is a read-only property; the code to the right of the '=>' is evaluated every time the property is invoked and the result of the expression is returnedpublic int Age => (int) (DateTime.Now - new DateTime(1990, 01, 19)).TotalYears;// PrintAge is a method, the code to the right of the '=>' is executed when the function is invokedpublic void PrintAge() => Console.WriteLine(Age);
}

? “表達式主體成員” 在 C# 7.0 中添加了一些進一步的支持:

class MyClass {int _age;// Property getter and setterpublic int Age { get => _age;set => _age = value >= 0 ?? value : throw new ArgumentOutOfRangeException(nameof(value));// Constructorpublic MyClass(int age) => Age = age;// Finalizer~MyClass() => ResourceManager.NotifyFinalizedMyClass(this);
}

? “更多表達主體的成員”

空傳播(“Elvis”運算符)

如果該對象不為空,則此運算符允許您訪問該對象的成員;或者簡單地將所有值折疊為 null 否則:

static void PrintUserName(UserDetails? user) {Console.WriteLine($"Name: {user?.Name ?? "No name"}, Age: {user?.Age.ToString() ?? "No age"}");
}static void Test() {PrintUserName(new UserDetails("Ben", 30)); // Prints "Name: Ben, Age: 30"PrintUserName(null); // Prints "Name: No name, Age: No age"
}

? “空條件運算符” 當將多個屬性/方法/字段調用鏈接在一起時(即var x = a?.B?.C()?.D),如果鏈中的任何單個元素為 null,則整個表達式將返回 null。

字符串插值(和格式化字符串)

到目前為止,這是我已經在各種示例中使用的功能。字符串插值允許以更自然的方式將變量嵌入到字符串中:

static void Test() {var name = "Ben";Console.WriteLine($"My name is {name}"); // The $ sign before the opening quotemark indicates this is an interpolated string
}

? “基本字符串插值” 可以通過格式后綴指定值轉換為字符串的方式。以下示例顯示了在將浮點值轉換為字符串時指定小數位數的一種方法:

static void Test() {var percentageComplete = 12.345d;Console.WriteLine($"Percentage complete: {percentageComplete:F0}%"); // Prints "Percentage complete: 12%"Console.WriteLine($"Percentage complete: {percentageComplete:F2}%"); // Prints "Percentage complete: 12.34%"
}

? “格式化字符串插值” 也可以指定對齊方式;用于打印 ASCII 表:

static void Test() {var names = new[] { "Ben", "Javier", "Chris" };var favoriteFoods = new[] { "Ramen", "Something Vegetarian", "No idea" };for (var i = 0; i < 3; ++i) {Console.WriteLine($"Name: {names[i],10} | Food: {favoriteFoods[i]}"); // Notice the ,10 that right-aligns names to a 10-column width}
}/* Prints:* Name:        Ben | Food: Ramen* Name:     Javier | Food: Something Vegetarian* Name:      Chris | Food: No idea
*/static void Test() {var names = new[] { "Ben", "Javier", "Chris" };var favoriteFoods = new[] { "Ramen", "Something Vegetarian", "No idea" };for (var i = 0; i < 3; ++i) {Console.WriteLine($"Name: {names[i],-10} | Food: {favoriteFoods[i]}"); // Notice the ,-10 that left-aligns names to a 10-column width}
}/* Prints:* Name: Ben        | Food: Ramen* Name: Javier     | Food: Something Vegetarian* Name: Chris      | Food: No idea
*/

? “對齊字符串插值” 對象的默認格式使用線程本地文化作為格式提供程序。有時這不是我們想要的。因此,我們可以通過顯式創建FormattableString然后將其轉換為字符串來手動指定格式提供程序:

static void Test() {var percentageComplete = 12.345d;FormattableString str = $"Percentage complete: {percentageComplete:F2}%";Console.WriteLine(str.ToString(CultureInfo.GetCultureInfo("de-DE"))); // Prints "Percentage complete: 12,35%" (German-style number formatting)
}

? “FormattableString”

"nameof" 運算符

這個小功能允許您將代碼中的標記名稱轉換為字符串。它很有用,因為它避免了在重命名這些類型時手動寫出成員/類型名稱的問題:

class User {public string Name { get; }public User(string name) {if (name == null) throw new ArgumentNullException(nameof(name)); // If we rename name later this will not compile (which is good)Name = name;}
}

? “nameof”

關聯集合的替代初始化語法

這是一個小功能。它允許使用更簡潔的語法來初始化關聯集合(即主要是字典)。以下兩個初始化是相同的:

class User {static void Test() {var oldWay = new Dictionary<int, string> {{ 1, "One" },{ 2, "Two" },{ 3, "Three" },{ 4, "Four" }};var newWay = new Dictionary<int, string> {[1] = "One",[2] = "Two",[3] = "Three",[4] = "Four"};}
}

?“舊字典初始化與新字典初始化” 字典鍵和值可以是任何類型。

集合初始化器的擴展“添加”方法

假設您正在使用的庫中定義了一個集合類型(必須實現IEnumerable<> );但是添加元素的方法沒有命名為Add(T item)。這是集合初始化器工作的要求。

下面是一個使用名為UserDatabase的虛構類型的示例,該類型從虛構的第三方庫中實現IEnumerable?:

static void Test() {// Won't compile// Doesn't work becuase UserDatabase calls its add method AddUser(), so we have to use the second approach belowvar database = new UserDatabase {new User("Ben", 30),new User("Seb", 27),new User("Rob", 33)};// Will compile but less prettyvar database = new UserDatabase();database.AddUser(new User("Ben", 30));database.AddUser(new User("Seb", 27));database.AddUser(new User("Rob", 33));
}

? “嘗試使用集合初始化程序時沒有添加方法” 在這種情況下,從 C# 6.0 開始,我們可以指定Add(T item)擴展方法來啟用集合初始值設定項:

static class UserDatabaseExtensions {public static void Add(this UserDatabase @this, User u) => @this.AddUser(u);
}// ...static void Test() {// Hooray, this works now!var database = new UserDatabase {new User("Ben", 30),new User("Seb", 27),new User("Rob", 33)};
}

? “嘗試使用集合初始化程序時添加擴展方法”

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/282662.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/282662.shtml
英文地址,請注明出處:http://en.pswp.cn/news/282662.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

非涉密計算機檢查的通知,關于開展非涉密計算機及可移動存儲介質專項清理活動的緊急通知...

關于在全校范圍內開展非涉密計算機及可移動存儲介質專項清理活動的緊急通知密辦字[2009]01號各單位&#xff1a;為有效遏制木馬病毒和惡意代碼的蔓延趨勢&#xff0c;現在校內開展一次非涉密計算機及可移動存儲介質的專項清理活動&#xff0c;要求如下&#xff1a;1、所有涉密人…

Spring Cloud構建微服務架構:服務消費(基礎)

使用LoadBalancerClient在Spring Cloud Commons中提供了大量的與服務治理相關的抽象接口&#xff0c;包括DiscoveryClient、這里我們即將介紹的LoadBalancerClient等。對于這些接口的定義我們在上一篇介紹服務注冊與發現時已經說過&#xff0c;Spring Cloud做這一層抽象&#x…

oracle數據庫中VARCHAR2(50 CHAR) 和VARCHAR2(50) 有啥區別?

VARCHAR2&#xff08;50 char&#xff09;這種類型的字段最多放50個字符&#xff0c;不夠50個用空格填充&#xff1b;而VARCHAR2(50)最大允許存放50個字符&#xff0c;但是不足50個也不用空格填充。varchar2是變長字符串&#xff0c;與CHAR類型不同&#xff0c;它不會使用空格填…

《解密小米之互聯網下的商業奇跡》

解密小米《解密小米之互聯網下的商業奇跡》 磐石之心 清華大學出版社 2014/10/1 書籍&#xff1a;《非同凡響想,喬布斯啟示錄》 磐石之心&#xff1a;原名王斌&#xff0c;互聯網IT資深預言家&#xff0c;第一個提出互聯網未來競爭是在線生活方式的競爭&#xff1b;第一個提出3…

計算機內存的故障,計算機內存出現故障的解決方法

內存如果出現故障&#xff0c;會造成系統運行不穩定、程序異常出錯和*作系統無法安裝的故障&#xff0c;下面將列舉內存常見的故障排除實例。1)內存順序引起的計算機工作不正常故障現象&#xff1a;一臺p4計算機&#xff0c;使用的是華碩intel850芯片組的主板&#xff0c;兩條r…

2018暑假集訓---遞推遞歸----一只小蜜蜂hdu2044

一只小蜜蜂... Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 93249 Accepted Submission(s): 33187Problem Description 有一只經過訓練的蜜蜂只能爬向右側相鄰的蜂房&#xff0c;不能反向爬行。請編程計算蜜…

《ASP.NET Core 6框架揭秘》實例演示[28]:自定義一個服務器

作為ASP.NET Core請求處理管道的“龍頭”的服務器負責監聽和接收請求并最終完成對請求的響應。它將原始的請求上下文描述為相應的特性&#xff08;Feature&#xff09;&#xff0c;并以此將HttpContext上下文創建出來&#xff0c;中間件針對HttpContext上下文的所有操作將借助于…

高清攝像頭MIPI接口與ARM連接【轉】

本文轉載自&#xff1a;http://www.cnblogs.com/whw19818/p/5811299.html MIPI攝像頭常見于手機、平板中&#xff0c;支持500萬像素以上高清分辨率。它的全稱為“Mobile Industry Processor Interface”&#xff0c;分為MIPI DSI 和MIPI CSI&#xff0c;分別對應于視頻顯示和視…

算法(第4版)Robert Sedgewick 刷題 第一章(1)

/*** Description 顛倒數組排列順序* author SEELE* date 2017年8月17日 上午10:56:17* action sortArr*/public static void sortArr() {int[] b new int[6];int[] a { 1, 2, 3, 4, 5, 6, 7 };for (int i 0; i < a.length / 2; i) {int temp a[a.length - 1 - i];a[a.l…

9種排序算法在四種數據分布下的速度比較

9種算法分別是&#xff1a; 1.選擇排序 2.希爾排序 3.插入排序 4.歸并排序 5.快速排序 6.堆排序 7.冒泡排序 8.梳排序 9.雞尾酒排序 在不同的情形下&#xff0c;排序速度前三名也不盡相同 Random : 希爾>快排>歸并 Few unique : 快排>…

win7服務器端口被占用,高手親自幫您win7端口被占用的詳盡處理要領

今天有一位用戶說他安裝了win7系統以后&#xff0c;在使用中突然遇到了win7端口被占用的情況&#xff0c;估計還會有更多的網友以后也會遇到win7端口被占用的問題&#xff0c;所以今天我們先來分析分析&#xff0c;那我們要怎么面對這個win7端口被占用的問題呢&#xff1f;大家…

局部變量和參數傳遞的問題

<SCRIPT LANGUAGE"JavaScript">var bb 1;function aa(bb) { //這里傳遞參數相當于 var bb bb ;給形參bb賦值為1。&#xff08;又參數傳遞&#xff0c;相當于就是在函數中定義了一個局部變量并且給這個變量賦了初值1&#xff09;此bb非彼bb&#xff0c;是分別…

回車ajax顯示,ajax返回值中有回車換行、空格的解決方法分享

最近在寫一個頁面&#xff0c;用jquery ajax來實現判斷&#xff0c;剛寫好測試完全沒有問題&#xff0c;過了兩天發現出現問題&#xff0c;判斷不成了。后來發現所有alert出來的返回值前面都會加若干換行和空格。(至今不明白&#xff0c;同一臺電腦&#xff0c;同樣的環境&…

PHP插入排序

本意是想研究一下希爾排序的,因為希爾排序和快速排序沒有爭議的是排序最快的兩種算法,但無奈希爾排序是以插入排序為基礎的,所以只得先研究一下插入排序. 插入排序基本思想: 插入排序(Insertion Sort)的基本思想是&#xff1a;每次將一個待排序的記錄&#xff0c;按其關鍵字大小…

使用Stepping.NET輕松執行多步原子操作

Stepping 是一個基于 BASE 的分布式作業實現。它可以作為工作流引擎&#xff0c;事件收/發件箱&#xff0c;用于郵箱/短信發送&#xff0c;用于遠程接口調用等場景。Stepping 中 Job 和 Step 是什么?Job 是一個分布式事務單元&#xff0c;而 Step 是 job 中一個特定的任務。一…

JSP+JavaBean+Servlet技術(MVC模型)

一&#xff0c;Servlet開發用戶在瀏覽器中輸入一個網址并回車&#xff0c;瀏覽器會向服務器發送一個HTTP請求。服務器端程序接受這個請求&#xff0c;并對請求進行處理&#xff0c;然后發送一個回應。瀏覽器收到回應&#xff0c;再把回應的內容顯示出來。這種請求—響應模式就是…

ora-01591:鎖被未分布式事物處理/Distrib tran

伴隨報錯內容&#xff1a;Distrib tran xxx.xxx.xx.x.xxxx 1、使用Oracle DBA用戶&#xff0c;查詢如下數據字典&#xff1a;select * from dba_2pc_pending2、強制Rollback或者Commit該事務&#xff1a;select commit force || local_tran_id||; from dba_2pc_pending…

bzoj2721 [Violet 5]櫻花

分析&#xff1a;這道題對于我這種蒟蒻來說還是很有難度啊。 思路非常巧妙&#xff0c;既然不定方程要有有限個數解&#xff0c;那么這個肯定會對解有所限制&#xff0c;也就是本題中的正整數.這個時候我們要表示出方程中的一個根x,設z n!,那么xyz/(y-z),這樣的話不能得到答案…

ipados 文件 連接服務器,iPadOS更新指南,總有一個功能是你需要的

近期&#xff0c;蘋果向部分ipad用戶推送了iPadOS系統&#xff0c;據系統介紹&#xff0c;這是一款強大的操作系統&#xff0c;更能體現iPad的獨特之處。iPadOS與IOS同源&#xff0c;針對iPad的大顯示屏和多功能增加了全新和直觀的強大功能。剛才小編給大家提到了部分iPad用戶&…

Angular 2.x 從0到1 (五)史上最簡單的Angular2教程

第一節&#xff1a;Angular 2.0 從0到1 &#xff08;一&#xff09;第二節&#xff1a;Angular 2.0 從0到1 &#xff08;二&#xff09;第三節&#xff1a;Angular 2.0 從0到1 &#xff08;三&#xff09;第四節&#xff1a;Angular 2.0 從0到1 &#xff08;四&#xff09;第五…