欧美vvv,亚洲第一成人在线,亚洲成人欧美日韩在线观看,日本猛少妇猛色XXXXX猛叫

新聞資訊

    # 是一種通用、類型安全、面向對象的編程語言。該語言的目標是程序員的生產力。為此,C# 平衡了簡單性、表現力和性能。自第一個版本以來,該語言的首席架構師是Anders Hejlsberg(Turbo Pascal的創建者和Delphi的架構師)。C# 語言與平臺無關,適用于一系列特定于平臺的運行時。

    面向對象

    C# 是面向對象范例的豐富實現,其中包括、和。封裝意味著在周圍創建邊界,以將其外部(公共)行為與其內部(私有)實現細節分開。從面向對象的角度來看,以下是 C# 的獨特功能:

    統一型系統

    C# 中的基本構建基塊是稱為數據和函數的封裝單元。C# 具有,其中所有類型最終共享一個公共基類型。這意味著所有類型,無論它們表示業務對象還是基元類型(如數字),都共享相同的基本功能。例如,任何類型的實例都可以通過調用其 ToString 方法轉換為字符串。

    類和接口

    在傳統的面向對象范式中,唯一的類型是類。在 C# 中,還有其他幾種類型,其中一種是。接口就像一個無法保存數據的類。這意味著它只能定義(而不是),這允許多重繼承以及規范和實現之間的分離。

    屬性、方法和事件

    在純面向對象的范式中,所有函數都是。在 C# 中,方法只是一種,它還包括和事件(還有其他屬性和)。屬性是封裝對象狀態片段(如按鈕的顏色或標簽的文本)的函數成員。事件是簡化對對象狀態更改的操作的函數成員。

    盡管 C# 主要是一種面向對象的語言,但它也借鑒了函數式編程范;具體說來:

    函數可以被視為值

    使用,C# 允許函數作為值傳遞到其他函數或從其他函數傳遞。

    C# 支持純度模式

    函數式編程的核心是避免使用值發生變化的變量,而支持聲明性模式。C# 具有幫助處理這些模式的關鍵功能,包括能夠動態編寫“捕獲”變量( 表達式)的未命名函數,以及通過執行列表或響應式編程的能力。C# 還提供,這使得編寫(只讀)類型變得容易。

    類型安全

    C# 主要是一種語言,這意味著類型的實例只能通過它們定義的協議進行交互,從而確保每個類型的內部一致性。例如,C# 阻止您與類型交互,就好像它是類型一樣。

    更具體地說,C# 支持靜態類型,這意味著該語言在強制實施安全。這是對在強制實施的類型安全的補充。

    靜態類型甚至在程序運行之前就消除了一大類錯誤。它將負擔從運行時單元測試轉移到編譯器上,以驗證程序中的所有類型是否正確組合在一起。這使得大型程序更易于管理、更可預測且更健壯。此外,靜態類型允許Visual Studio中的IntelliSense等工具幫助您編寫程序,因為它知道給定變量的類型,因此可以對該變量調用哪些方法。此類工具還可以識別程序中使用變量、類型或方法的任何地方,從而實現可靠的重構。

    注意

    C# 還允許通過 dynamic 關鍵字動態鍵入部分代碼。但是,C# 仍然是一種主要是靜態類型的語言。

    C# 也稱為,因為它的類型規則是嚴格強制執行的(無論是靜態還是在運行時)。例如,不能調用旨在接受具有浮點數的整數的函數,浮點數顯式轉換為整數。這有助于防止錯誤。

    內存管理

    C# 依賴于運行時來執行自動內存管理。公共語言運行庫有一個垃圾回收器,該回收器作為程序的一部分執行,為不再引用的對象回收內存。這使程序員不必顯式地為對象釋放內存,從而消除了在C++等語言中遇到的錯誤指針的問題。

    C# 不會消除指針:它只是使大多數編程任務不需要指針。對于性能關鍵型熱點和互操作性,允許在標記為不安全的塊中使用指針和顯式內存分配。

    平臺支持

    C# 具有支持以下平臺的運行時:

    • Windows Desktop 7-11(適用于富客戶端、Web、服務器和命令行應用程序)
    • macOS(適用于富客戶端、Web 和命令行應用程序)
    • Linux 和 macOS(用于 Web 和命令行應用程序)
    • 安卓和iOS(用于移動應用程序)
    • Windows 10 設備(Xbox、Surface Hub 和 HoloLens)

    還有一種稱為 的技術,可以將 C# 編譯為在瀏覽器中運行的 Web 程序集。

    CLR、BCL 和運行時

    C# 程序的運行時支持包括和。運行時還可以包括更高級別的,其中包含用于開發胖客戶端、移動或 Web 應用程序的庫(參見)。存在不同的運行時以允許不同類型的應用程序以及不同的平臺。


    公共語言運行庫

    (CLR) 提供必要的運行時服務,如自動內存管理和異常處理。(“common”一詞是指同一運行時可以由其他編程語言(如 F#、Visual Basic 和托管C++)共享的事實。

    C# 之所以稱為托管語言,是因為它將源代碼編譯為代碼,托管代碼以 (IL) 表示。CLR 將 IL 轉換為計算機的本機代碼,如 X64 或 X86,通常在執行之前。這稱為實時 (JIT) 編譯。提前編譯也可用于縮短大型程序集或資源受限設備的啟動時間(并在開發移動應用程序時滿足 iOS 應用商店規則)。

    托管代碼的容器稱為。程序集不僅包含 IL,還包含類型信息()。元數據的存在允許程序集引用其他程序集中的類型,而無需其他文件。

    注意

    您可以使用Microsoft的 工具檢查和反匯編程序集的內容。使用ILSpy或JetBrain的dotPeek等工具,您可以更進一步將IL反編譯為C#。由于 IL 比本機機器代碼級別更高,因此反編譯器可以很好地重建原始 C#。

    程序可以查詢自己的元數據(反射),甚至可以在運行時生成新的 IL()。

    基類庫

    CLR 始終附帶一組稱為 (BCL) 的程序集。BCL 為程序員提供核心功能,例如集合、輸入/輸出、文本處理、XML/JSON 處理、網絡、加密、互操作、并發和并行編程。

    BCL 還實現 C# 語言本身所需的類型(用于枚舉、查詢和異步等功能),并允許您顯式訪問 CLR 的功能,如反射和內存管理。

    運行時

    (也稱為)是下載和安裝的可部署單元。運行時由 CLR(及其 BCL)以及特定于您正在編寫的應用程序類型(Web、移動、富客戶端等)的可選應用程序層組成(如果要編寫命令行控制臺或非 UI 庫,則不需要應用程序層。

    編寫應用程序時,以特定運行時,這意味著應用程序使用并依賴于運行時提供的功能。運行時的選擇還決定了應用程序將支持哪些平臺。

    下表列出了主要的運行時選項:

    應用層

    CLR/BCL

    程序類型

    運行在...

    ASP.NET

    .NET 6

    Windows, Linux, macOS

    視窗桌面

    .NET 6

    窗戶

    視窗 7-10+

    毛伊島(2022年初)

    .NET 6

    移動設備、桌面版

    iOS, 安卓, 蘋果操作系統, 視窗 10+

    WinUI 3(2022 年初)

    .NET 6

    贏10

    視窗 10+ 桌面

    UWP

    .NET Core 2.2

    Win10 + Win10 設備

    Windows 10+ 桌面和設備

    (Legacy) .NET Framework

    .NET 框架

    網頁, 視窗

    視窗 7-10+

    以圖形方式顯示了此信息,也可作為本書所涵蓋內容的指南。


    C 語言的運行時#

    .NET 6

    .NET 6 是 Microsoft 的旗艦開源運行時。您可以編寫在 Windows、Linux 和 macOS 上運行的 Web 和控制臺應用程序,在 Windows 7 到 11 和 macOS 上運行的胖客戶端應用程序,以及在 iOS 和 Android 上運行的移動應用程序。本書重點介紹.NET 6 CLR和BCL。

    與.NET Framework不同,.NET 6沒有預安裝在Windows機器上。如果在不存在正確運行時的情況下嘗試運行 .NET 6 應用程序,則會出現一條消息,將您定向到可在其中下載運行時的網頁。可以通過創建部署來避免這種情況,該部署包括應用程序所需的運行時部分。

    注意

    .NET 6的前身是.NET 5,其前身是.NET Core 3。(Microsoft從名稱中刪除了“核心”,并跳過了版本 4)。跳過版本的原因是為了避免與 4.x混淆。

    這意味著在大多數情況下,在 .NET Core 版本 1、2 和 3(以及 .NET 5)下編譯的程序集將在 .NET 6 下無需修改即可運行。相反,在(任何版本的).NET Framework 下編譯的程序集通常與 .NET 6 不兼容。

    .NET 6 BCL和CLR與.NET 5(和.NET Core 3)非常相似,其區別主要集中在性能和部署上。

    毛 伊 島

    (多平臺應用程序 UI,2022 年初)旨在創建適用于 iOS 和 Android 的移動應用程序,以及適用于 macOS 和 Windows 的跨平臺桌面應用程序。MAUI 是 Xamarin 的演變,允許單個項目面向多個平臺。

    UWP 和 WinUI 3

    (UWP) 旨在編寫在 Windows 10+ 桌面和設備(Xbox、Surface Hub 和 HoloLens)上運行的沉浸式觸摸優先應用程序。UWP 應用經過沙盒處理,并通過 Windows 應用商店提供。UWP 預裝在 Windows 10 中。它使用 .NET Core 2.2 CLR/BCL 的版本,并且不太可能更新此依賴項。相反,Microsoft發布了一個名為的繼任者,作為的一部分。

    Windows 應用 SDK 適用于最新的 .NET,與 .NET 桌面 API 更好地集成,并且可以在沙盒外部運行。但是,它尚不支持Xbox或HoloLens等設備。

    .NET 框架

    是 Microsoft 最初的僅限 Windows 的運行時,用于編寫(僅)在 Windows 桌面/服務器上運行的 Web 和富客戶端應用程序。沒有計劃發布重大的新版本,但由于現有應用程序的豐富性,Microsoft將繼續支持和維護當前的 4.8 版本。

    在.NET Framework中,CLR/BCL與應用程序層集成在一起。用 .NET Framework 編寫的應用程序可以在 .NET 6 下重新編譯,盡管它們通常需要一些修改。.NET Framework 的某些功能在 .NET 6 中不存在(反之亦然)。

    .NET Framework 預裝在 Windows 中,并通過 Windows Update 自動修補。當您面向 .NET Framework 4.8 時,可以使用 C# 7.3 及更早版本的功能。

    注意

    長期以來,“.NET”一詞一直被用作包含“.NET”一詞的任何技術(.NET Framework,.NET Core,.NET Standard等)的總稱。

    這意味著Microsoft將.NET Core重命名為.NET造成了不幸的歧義。在本書中,我們將新的.NET稱為。為了提到.NET Core及其后續版本,我們將使用短語“.NET Core和.NET 5+”。

    更令人困惑的是,.NET(5+)是一個框架,但它與非常不同。因此,在可能的情況下,我們將優先使用術語而不是。

    利基運行時

    還有以下利基運行時:

    • .NET Micro Framework 用于在資源高度受限的嵌入式設備(小于 1 MB)上運行 .NET 代碼。
    • Unity 是一個游戲開發平臺,允許使用 C# 編寫游戲邏輯腳本。

    也可以在 SQL Server 中運行托管代碼。通過 SQL Server CLR 集成,可以使用 C# 編寫自定義函數、存儲過程和聚合,然后從 SQL 調用它們。它與 .NET Framework 和特殊的“托管”CLR 結合使用,后者強制實施沙箱以保護 SQL Server 進程的完整性。

    C語言簡史#

    以下是每個 C# 版本中新功能的反向時間順序,以便已經熟悉該語言舊版本的讀者受益。

    C# 10 中的新增功能

    C# 10 隨 Visual Studio 2022 一起提供,并在面向 .NET 6 時使用。

    文件范圍的命名空間

    在文件中所有類型都在單個命名空間中定義的常見情況下,C# 10 中的聲明可減少混亂并消除不必要的縮進級別:

    namespace MyNamespace;  // Applies to everything that follows in the file.
    
    class Class1 {}         // inside MyNamespace
    class Class2 {}         // inside MyNamespace

    全局使用指令

    在 using 指令前面加上 global 關鍵字時,它會將該指令應用于項目中的所有文件:

    global using System;
    global using System.Collection.Generic;

    這樣可以避免在每個文件中重復相同的指令。全局 using 指令與 using static .

    此外,.NET 6 項目現在支持:如果在項目文件中將 ImplicitUsings 元素設置為 true,則會自動導入最常用的命名空間(基于 SDK 項目類型)。有關更多詳細信息,請參閱中的

    匿名類型的非破壞性突變

    C# 9 引入了 with 關鍵字,用于對記錄執行非破壞性更改。在 C# 10 中,with 關鍵字也適用于匿名類型:

    var a1 = new { A = 1, B = 2, C = 3, D = 4, E = 5 };
    var a2 = a1 with { E = 10 }; 
    Console.WriteLine (a2);      // { A = 1, B = 2, C = 3, D = 4, E = 10 }

    新的解構語法

    C# 7 引入了元組(或使用解構方法的任何類型的元組)的解構語法。C# 10 更進一步擴展了此語法,允許您在同一解構中混合賦值和聲明:

    var point = (3, 4);
    double x = 0;
    (x, double y) = point;

    結構中的字段初始值設定項和無參數構造函數

    從 C# 10 開始,可以在結構中包含字段初始值設定項和無參數構造函數(請參閱中的)。這些僅在顯式調用構造函數時執行,因此可以輕松繞過 - 例如,通過默認關鍵字。引入此功能主要是為了結構記錄。

    記錄結構

    記錄最初是在 C# 9 中引入的,它們充當編譯增強類。在 C# 10 中,記錄也可以是結構:

    record struct Point (int X, int Y); 

    規則在其他方面是相似的:記錄結構與具有大致相同的功能(請參閱中的)。 例外情況是,編譯器在記錄結構上生成的屬性是可寫的,除非您在記錄聲明前面加上 readonly 關鍵字。

    Lambda 表達式增強功能

    圍繞 lambda 表達式的語法已通過多種方式得到增強。首先,允許隱式類型 ( var ):

    var greeter = () => "Hello, world";

    lambda 表達式的隱式類型是 Action 或 Func 委托,因此在這種情況下,greeter 的類型為 Func<string> 。必須顯式聲明任何參數類型:

    var square = (int x) => x * x;

    其次,lambda 表達式可以指定返回類型:

    var sqr = int (int x) => x;

    這主要是為了提高復雜嵌套 lambda 的編譯器性能。

    第三,您可以將 lambda 表達式傳遞到對象、委托或表達式類型的方法參數中:

    M1 (() => "test");   // Implicitly typed to Func<string>
    M2 (() => "test");   // Implicitly typed to Func<string>
    M3 (() => "test");   // Implicitly typed to Expression<Func<string>>
    
    void M1 (object x) {}
    void M2 (Delegate x) {}
    void M3 (Expression x) {}

    最后,您可以將屬性應用于 lambda 表達式的編譯生成的目標方法(及其參數和返回值):

    Action a = [Description("test")] () => { };

    有關更多詳細信息,請參閱中的

    嵌套屬性模式

    以下簡化語法在 C# 10 中對于嵌套屬性模式匹配是合法的(請參閱中的):

    var obj = new Uri ("https://www.linqpad.net");
    if (obj is Uri { Scheme.Length: 5 }) ...

    這相當于:

    if (obj is Uri { Scheme: { Length: 5 }}) ...

    調用者參數表達式

    應用 [CallerArgumentExpression] 屬性的方法參數從調用站點捕獲參數表達式:

    Print (Math.PI * 2);
    
    void Print (double number,
               [CallerArgumentExpression("number")] string expr = null)
      => Console.WriteLine (expr);
    
    // Output: Math.PI * 2

    此功能主要用于驗證和斷言庫(請參閱中的)。

    其他新功能

    #line 指令已在 C# 10 中得到增強,允許指定列和范圍。

    C# 10 中的內插字符串可以是常量,只要內插的值是常量即可。

    記錄可以在 C# 10 中密封 ToString() 方法。

    C# 的定賦值分析已得到改進,因此表達式如下:

    if (foo?.TryParse ("123", out var number) ?? false)
      Console.WriteLine (number);

    (在 C# 10 之前,編譯器將生成錯誤:“使用未賦值的局部變量'number'。

    C# 9.0 中的新增功能

    C# 9.0 隨 一起提供,并在面向 .NET 5 時使用。

    頂級語句

    使用(參見中的),您可以編寫一個沒有 Main 方法和 Program 類包袱的程序:

    using System;
    Console.WriteLine ("Hello, world");

    頂級語句可以包含方法(充當本地方法)。您還可以通過 “magic” args 變量訪問命令行參數,并向調用方返回一個值。頂級語句后可以跟類型和命名空間聲明。

    僅初始化設置器

    屬性聲明中的僅(參見中的使用 init 關鍵字而不是 set 關鍵字:

    class Foo { public int ID { get; init; } }

    這類似于只讀屬性,只是它也可以通過對象初始值設定項進行設置:

    var foo = new Foo { ID = 123 };

    這使得創建可通過對象初始值設定項而不是構造函數填充的不可變(只讀)類型成為可能,并有助于避免接受大量可選參數的構造函數的反模式。僅初始化設置器在中使用時還允許。

    記錄

    (參見中的是一種特殊的類,旨在很好地處理不可變數據。它最特別的特點是關鍵字(帶有):

    Point p1 = new Point (2, 3);
    Point p2 = p1 with { Y = 4 };   // p2 is a copy of p1, but with Y set to 4
    Console.WriteLine (p2);         // Point { X = 2, Y = 4 }
    
    record Point
    {
      public Point (double x, double y) => (X, Y) = (x, y);
    
      public double X { get; init; }
      public double Y { get; init; }    
    }

    在簡單情況下,記錄還可以消除定義屬性以及編寫構造函數和解構函數的樣板代碼。我們可以將點記錄定義替換為以下內容,而不會丟失功能:

    record Point (double X, double Y);

    與元組一樣,默認情況下,記錄表現出結構相等性。記錄可以對其他記錄進行子類化,并且可以包含類可以包含的相同構造。編譯器在運行時將記錄實現為類。

    模式匹配改進

    (參見中的允許 <、>、<= 和 >= 運算符出現在模式中:

    string GetWeightCategory (decimal bmi) => bmi switch {
      < 18.5m => "underweight",
      < 25m => "normal",
      < 30m => "overweight",
      _ => "obese" };

    使用,您可以通過三個新關鍵字( 和 , or 和 not )組合模式:

    bool IsVowel (char c) => c is 'a' or 'e' or 'i' or 'o' or 'u';
    
    bool IsLetter (char c) => c is >= 'a' and <= 'z'
                                or >= 'A' and <= 'Z';

    與 && 和 || 一樣運算符,并且具有高于 或 的優先級。您可以使用括號覆蓋此設置。

    not 組合器可以與類型模式一起使用,以測試對象是否是(不是):

    if (obj is not string) ...

    目標類型的新表達式

    構造對象時,C# 9 允許在編譯器可以明確推斷類型名稱時省略類型名稱:

    System.Text.StringBuilder sb1 = new();
    System.Text.StringBuilder sb2 = new ("Test");

    當變量聲明和初始化位于代碼的不同部分時,這特別有用:

    class Foo
    {
      System.Text.StringBuilder sb;
      public Foo (string initialValue) => sb = new (initialValue);
    }

    在以下情況下:

    MyMethod (new ("test"));
    void MyMethod (System.Text.StringBuilder sb) { ... }

    有關詳細信息,請參閱中的

    互操作改進

    C# 9 引入了函數指針(請參閱 章中的“函數指針”和第 中的)。 它們的主要用途是允許非托管代碼在 C# 中調用靜態方法,而無需委托實例的開銷,并且能夠在參數和返回類型可 (在每一端以相同方式表示)時繞過 P/Invoke 層。

    C# 9 還引入了 nint 和 nuint 本機大小的整數類型(請參閱中的),這些類型在運行時映射到 System.IntPtr 和 System.UIntPtr 。在編譯時,它們的行為類似于支持算術運算的數字類型。

    其他新功能

    此外,C# 9 現在允許你:

    • 重寫方法或只讀屬性,使其返回派生類型(請參閱中的)
    • 將屬性應用于本地函數(請參閱中的)
    • 將 static 關鍵字應用于 lambda 表達式或局部函數,以確保不會意外捕獲局部變量或實例變量(請參閱中的)
    • 通過編寫 GetEnumerator 擴展方法,使任何類型都使用 foreach 語句
    • 定義在首次加載程序集時執行一次的方法,方法是將 [ModuleInitializer] 屬性應用于(靜態無參數)方法
    • 使用“丟棄”(下劃線符號)作為 lambda 表達式參數
    • 編寫必須實現的方法 - 啟用 Roslyn 的新等方案(請參閱中的)
    • 將屬性應用于方法、類型或模塊,以防止運行時初始化局部變量(請參閱中的)

    C# 8.0 中的新增功能

    C# 8.0 首次隨 一起提供,今天在面向 .NET Core 3 或 .NET Standard 2.1 時仍在使用。

    指數和范圍

    簡化了數組的元素或部分(或低級類型 Span<T> 和 ReadOnlySpan<T> )的使用。

    索引允許您使用 ^ 運算符引用相對于數組的元素。^1 表示最后一個元素,^2 表示倒數第二個元素,依此類推:

    char[] vowels = new char[] {'a','e','i','o','u'};
    char lastElement  = vowels [^1];   // 'u'
    char secondToLast = vowels [^2];   // 'o'

    范圍允許您使用 ..算子:

    char[] firstTwo =  vowels [..2];    // 'a', 'e'
    char[] lastThree = vowels [2..];    // 'i', 'o', 'u'
    char[] middleOne = vowels [2..3]    // 'i'
    char[] lastTwo =   vowels [^2..];   // 'o', 'u'

    C# 借助索引和范圍類型實現索引和范圍:

    Index last = ^1;
    Range firstTwoRange = 0..2;
    char[] firstTwo = vowels [firstTwoRange];   // 'a', 'e'

    可以通過定義參數類型為 Index 或 Range 的索引器來支持自己的類中的索引和范圍:

    class Sentence
    {
      string[] words = "The quick brown fox".Split();
    
      public string this   [Index index] => words [index];
      public string[] this [Range range] => words [range];
    }

    有關更多信息,請參閱中的

    零合并分配

    這??= 運算符僅在變量為 null 時才分配變量。而不是

    if (s == null) s = "Hello, world";

    您現在可以這樣寫:

    s ??= "Hello, world";

    使用聲明

    如果省略 using 語句后面的方括號和語句塊,則它將成為 。然后,當執行落在語句塊之外時,將釋放資源:

    if (File.Exists ("file.txt"))
    {
      using var reader = File.OpenText ("file.txt");
      Console.WriteLine (reader.ReadLine());
      ...
    }

    在這種情況下,當執行落在 if 語句塊之外時,將釋放讀取器。

    只讀成員

    C# 8 允許您將只讀修飾符應用于結構的函數,確保如果嘗試修改任何字段,則會生成編譯時錯誤:

    struct Point
    {
      public int X, Y;
      public readonly void ResetX() => X = 0;  // Error!
    } 

    如果只讀函數調用非只讀函數,編譯器將生成警告(并防御性地復制結構以避免發生突變的可能性)。

    靜態本地方法

    將 static 修飾符添加到局部方法可防止它看到封閉方法的局部變量和參數。這有助于減少耦合,并使本地方法能夠隨心所欲地聲明變量,而不會有與包含方法中的變量發生沖突的風險。

    默認接口成員

    C# 8 允許您向接口成員添加默認實現,使其成為可選的實現:

    interface ILogger
    {
      void Log (string text) => Console.WriteLine (text);
    }

    這意味著您可以在不中斷實現的情況下向接口添加成員。默認實現必須通過接口顯式調用:

    ((ILogger)new Logger()).Log ("message");

    接口還可以定義靜態成員(包括字段),這些成員可以從默認實現中的代碼訪問:

    interface ILogger
    {
      void Log (string text) => Console.WriteLine (Prefix + text);
      static string Prefix = ""; 
    }

    或從接口外部,除非通過靜態接口成員(例如私有、受保護或內部)上的可訪問性修飾符進行限制:

    ILogger.Prefix = "File log: ";

    禁止使用實例字段。有關更多詳細信息,請參閱中的

    切換表達式

    從 C# 8 開始,可以在的上下文中使用 switch:

    string cardName = cardNumber switch    // assuming cardNumber is an int
    {
      13 => "King",
      12 => "Queen",
      11 => "Jack",
      _ => "Pip card"   // equivalent to 'default'
    };

    有關更多示例,請參閱中的

    元組、位置和屬性模式

    C# 8 支持三種新模式,主要是為了 switch 語句/表達式(請參閱中的)。允許您打開多個值:

    int cardNumber = 12; string suite = "spades";
    string cardName = (cardNumber, suite) switch
    {
      (13, "spades") => "King of spades",
      (13, "clubs") => "King of clubs",
      ...
    };

    模式允許對公開解構函數的對象使用類似的語法,允許您匹配對象的屬性。您可以在開關中和 is 運算符中使用所有模式。下面的示例使用來測試 obj 是否為長度為 4 的字符串:

    if (obj is string { Length:4 }) ...

    可為空的引用類型

    可為 null 類型為值類型帶來可為空性,而 的引用類型則相反,為引用類型帶來(一定程度的),目的是幫助避免 NullReferenceExceptions。可為 null 的引用類型引入了一種安全級別,當編譯器檢測到存在生成 NullReferenceException 風險的代碼時,該級別純粹由編譯器以警告或錯誤的形式強制實施。

    可以在項目級別(通過 項目文件中的 Nullable 元素)或在代碼(通過 #nullable 指令)啟用可為 null 的引用類型。啟用后,編譯器會將非可為空性設為默認值:如果希望引用類型接受 null,則必須應用 ?指示后綴:

    #nullable enable    // Enable nullable reference types from this point on
    
    string s1 = null;   // Generates a compiler warning! (s1 is non-nullable)
    string? s2 = null;  // OK: s2 is nullable reference type

    未初始化的字段也會生成警告(如果類型未標記為可為空),如果編譯器認為可能發生 NullReferenceException,則取消引用可為空的引用類型也是如此:

    void Foo (string? s) => Console.Write (s.Length);  // Warning (.Length)

    若要刪除警告,可以使用 ( !

    void Foo (string? s) => Console.Write (s!.Length);

    有關完整討論,請參閱中的

    異步流

    在 C# 8 之前,可以使用 yield return 編寫,或等待編寫。但是你不能同時做這兩件事,并編寫一個等待的迭代器,異步生成元素。C# 8 通過引入來解決此問題:

    async IAsyncEnumerable<int> RangeAsync (
      int start, int count, int delay)
    {
      for (int i = start; i < start + count; i++)
      {
        await Task.Delay (delay);
        yield return i;
      }
    }

    await foreach 語句使用異步流:

    await foreach (var number in RangeAsync (0, 10, 100))
      Console.WriteLine (number);

    有關詳細信息,請參閱中的

    C# 7.x 中的新增功能

    C# 7.x 最初隨 Visual Studio 2017 一起提供。今天,當您面向.NET Core 7,.NET Framework 3.2019至2.4或.NET Standard 6.4時,Visual Studio 8仍在使用C# 2.0。

    C# 7.3

    C# 7.3 對現有功能進行了細微改進,例如允許將相等運算符與元組一起使用、改進重載分辨率以及將特性應用于自動屬性的支持字段的功能:

    [field:NonSerialized]
    public int MyProperty { get; set; }

    C# 7.3 還基于 C# 7.2 的高級低分配編程功能構建,能夠重新分配 ,在索引固定字段時無需固定,并且使用 stackalloc 支持字段初始值設定項:

    int* pointer  = stackalloc int[] {1, 2, 3};
    Span<int> arr = stackalloc []    {1, 2, 3};

    請注意,堆棧分配的內存可以直接分配給 Span<T> 。我們將在第 中描述跨度,以及為什么要使用它們。

    C# 7.2

    C# 7.2 添加了一個新的私有受保護修飾符(內部修飾符和受保護修飾符的),在調用方法時跟隨帶有位置參數的命名參數的功能,以及只讀結構。只讀結構強制所有字段都是只讀的,以幫助聲明意圖并允許編譯器更大的優化自由度:

    readonly struct Point
    {
      public readonly int X, Y;   // X and Y must be readonly
    }

    C# 7.2 還添加了專門的功能來幫助進行微優化和低分配編程:請參閱 章中的“引用”和“,以及中的

    C# 7.1

    從 C# 7.1 開始,如果可以推斷出類型,則可以在使用默認關鍵字時省略該類型:

    decimal number = default;   // number is decimal

    C# 7.1 還放寬了 switch 語句的規則(以便可以在泛型類型參數上進行模式匹配),允許程序的 Main 方法是異步的,并允許推斷元組元素名稱:

    var now = DateTime.Now;
    var tuple = (now.Hour, now.Minute, now.Second);

    數字文字改進

    C# 7 中的數字文本可以包含下劃線以提高可讀性。這些稱為數字分隔符,編譯器會忽略這些:

    int million = 1_000_000;

    可以使用 0b 前綴指定:

    var b = 0b1010_1011_1100_1101_1110_1111;

    輸出變量和丟棄

    C# 7 使調用包含 out 參數的方法變得更加容易。首先,您現在可以動態聲明(請參閱中的):

    bool successful = int.TryParse ("123", out int result);
    Console.WriteLine (result);

    當調用具有多個 out 參數的方法時劃線字符丟棄您不感興趣的方法:

    SomeBigMethod (out _, out _, out _, out int x, out _, out _, out _);
    Console.WriteLine (x);

    類型模式和模式變量

    您還可以使用 is 運算符動態引入變量。這些被稱為模式變量(參見中的):

    void Foo (object x)
    {
      if (x is string s)
        Console.WriteLine (s.Length);
    }

    switch 語句還支持類型模式,因此您可以打開常量(請參閱中的)。您可以使用 when 子句指定條件,也可以打開空值:

    switch (x)
    {
      case int i:
        Console.WriteLine ("It's an int!");
        break;
      case string s:
        Console.WriteLine (s.Length);    // We can use the s variable
        break;
      case bool b when b == true:        // Matches only when b is true
        Console.WriteLine ("True");
        break;
      case null:
        Console.WriteLine ("Nothing");
        break;
    }

    本地方法

    在另一個函數中聲明的方法(請參閱中的):

    void WriteCubes()
    {
      Console.WriteLine (Cube (3));
      Console.WriteLine (Cube (4));
      Console.WriteLine (Cube (5));
    
      int Cube (int value) => value * value * value;
    }

    局部方法僅對包含函數可見,并且可以像 lambda 表達式一樣捕獲局部變量。

    更多善于表達的成員

    C# 6 為方法、只讀屬性、運算符和索引器引入了表達式體“fat-arrow”語法。C# 7 將其擴展到構造函數、讀/寫屬性和終結器:

    public class Person
    {
      string name;
    
      public Person (string name) => Name = name;
    
      public string Name
      {
        get => name;
        set => name = value ?? "";
      }
    
      ~Person () => Console.WriteLine ("finalize");
    }

    解構函數

    C# 7 引入了解構模式(請參閱中的)。構造函數通常采用一組值(作為參數)并將它們分配給字段,而則執行相反的操作,并將字段分配回一組變量。我們可以在前面的示例中為 Person 類編寫一個解構函數,如下所示(除了異常處理):

    public void Deconstruct (out string firstName, out string lastName)
    {
      int spacePos = name.IndexOf (' ');
      firstName = name.Substring (0, spacePos);
      lastName = name.Substring (spacePos + 1);
    }

    解構函數使用以下特殊語法調用:

    var joe = new Person ("Joe Bloggs");
    var (first, last) = joe;          // Deconstruction
    Console.WriteLine (first);        // Joe
    Console.WriteLine (last);         // Bloggs

    元組

    也許對 C# 7 最顯著的改進是顯式支持(請參閱中的)。元組提供了一種存儲一組相關值的簡單方法:

    var bob = ("Bob", 23);
    Console.WriteLine (bob.Item1);   // Bob
    Console.WriteLine (bob.Item2);   // 23

    C# 的新元組是使用 System.ValueTuple<...>泛型結構。但是多虧了編譯器的魔力,元組元素可以命名為:

    var tuple = (name:"Bob", age:23);
    Console.WriteLine (tuple.name);     // Bob
    Console.WriteLine (tuple.age);      // 23

    使用元組,函數可以返回多個值,而無需求助于 out 參數或額外的類型包袱:

    static (int row, int column) GetFilePosition() => (3, 10);
    
    static void Main()
    {
      var pos = GetFilePosition();
      Console.WriteLine (pos.row);      // 3
      Console.WriteLine (pos.column);   // 10
    }

    元組隱式支持解構模式,因此您可以輕松地將它們為單個變量:

    static void Main()
    {
      (int row, int column) = GetFilePosition();   // Creates 2 local variables
      Console.WriteLine (row);      // 3 
      Console.WriteLine (column);   // 10
    }

    拋出表達式

    在 C# 7 之前,throw 始終是一個語句。現在,它也可以在表達式體函數中顯示為表達式:

    public string Foo() => throw new NotImplementedException();

    拋出表達式也可以出現在三元條件表達式中:

    string Capitalize (string value) =>
      value == null ? throw new ArgumentException ("value") :
      value == "" ? "" :
      char.ToUpper (value[0]) + value.Substring (1);

    C# 6.0 中的新增功能

    附帶的C# 0.2015具有新一代編譯器,完全用C#編寫。新的編譯器稱為項目“Roslyn”,通過庫公開整個編譯管道,允許您對任意源代碼執行代碼分析。編譯器本身是開源的,源代碼可在 獲得。

    此外,C# 6.0 還具有幾個次要但重要的增強功能,主要旨在減少代碼混亂。

    (“Elvis”)運算符(參見中的避免了在調用方法或訪問類型成員之前顯式檢查null。在下面的示例中,結果計算結果為 null,而不是拋出 NullReferenceException:

    System.Text.StringBuilder sb = null;
    string result = sb?.ToString();      // result is null

    (參見中的允許以 lambda 表達式的樣式更簡潔地編寫組成單個表達式的方法、屬性、運算符和索引器:

    public int TimesTwo (int x) => x * 2;
    public string SomeProperty => "Property value";

    ()允許您為自動屬性分配初始值:

    public DateTime TimeCreated { get; set; } = DateTime.Now;

    初始化的屬性也可以是只讀的:

    public DateTime TimeCreated { get; } = DateTime.Now;

    還可以在構造函數中設置只讀屬性,從而更輕松地創建不可變(只讀)類型。

    ()允許公開索引器的任何類型的單步初始化:

    var dict = new Dictionary<int,string>()
    {
      [3] = "three",
      [10] = "ten"
    };

    字符串(參見中的的簡潔替代方法。格式:

    string s = $"It is {DateTime.Now.DayOfWeek} today";

    (參見中的允許您將條件應用于 catch 塊:

    string html;
    try
    {
      html = await new HttpClient().GetStringAsync ("http://asef");
    }
    catch (WebException ex) when (ex.Status == WebExceptionStatus.Timeout)
    {
      ...
    }

    using static(參見中的指令允許您導入類型的所有靜態成員,以便您可以使用這些非限定成員:

    using static System.Console;
    ...
    WriteLine ("Hello, world");  // WriteLine instead of Console.WriteLine

    nameof()運算符以字符串形式返回變量、類型或其他符號的名稱。這樣可以避免在 Visual Studio 中重命名符號時中斷代碼:

    int capacity = 123;
    string x = nameof (capacity);   // x is "capacity"
    string y = nameof (Uri.Host);   // y is "Host"

    最后,您現在可以等待內部捕獲并最終阻止。

    C# 5.0 中的新增功能

    C# 5.0 的一大新功能是通過兩個新關鍵字 async 和 await 支持。異步函數支持,這使得編寫響應式和線程安全的胖客戶端應用程序變得更加容易。它們還可以輕松編寫高并發且高效的 I/O 綁定應用程序,這些應用程序不會占用每個操作的線程資源。我們將在第 中詳細介紹異步函數。

    C# 4.0 中的新增功能

    C# 4.0 引入了四個主要增強功能:

    ( 章和第 19 章)將(解析類型和成員的過程)從編譯時推遲到運行時,并且在需要復雜反射代碼的方案中非常有用。動態綁定在與動態語言和 COM 組件進行互操作時也很有用。

    ()允許函數指定默認參數值,以便調用方可以省略參數,參數允許函數調用方按名稱而不是位置標識參數。

    在 C# 4.0(和第 )中放寬了類型規則,以便泛型接口和泛型委托中的類型參數可以標記為變或,從而允許更自然的類型轉換。

    ()在 C# 4.0 中以三種方式得到增強。首先,參數可以在沒有 ref 關鍵字的情況下通過引用傳遞(與可選參數結合使用特別有用)。其次,可以而不是包含 COM 互操作類型的程序集。鏈接互操作類型支持類型等效性,避免了的需求,并結束了版本控制和部署難題。第三,從鏈接互操作類型返回 COM-Variant 類型的函數被映射到動態而不是對象,從而消除了強制轉換的需要。

    C# 3.0 中的新增功能

    添加到 C# 3.0 的功能主要集中在 (LINQ) 功能上。LINQ 允許直接在 C# 程序中編寫查詢并檢查其正確性,并查詢本地集合(如列表或 XML 文檔)或遠程數據源(如數據庫)。為支持 LINQ 而添加的 C# 3.0 功能包括隱式類型化局部變量、匿名類型、對象初始值設定項、lambda 表達式、擴展方法、查詢表達式和表達式樹。

    變量(var關鍵字,)允許您在聲明語句中省略變量類型,從而允許編譯器推斷它。這減少了混亂,并允許(),匿名類型是動態創建的簡單類,通常用于 LINQ 查詢的最終輸出。您還可以隱式類型化數組()。

    ()允許您在構造函數調用后以內聯方式設置屬性,從而簡化了對象構造。對象初始值設定項同時適用于命名類型和匿名類型。

    ()是由編譯器動態創建的微型函數;它們在“流暢”的 LINQ 查詢中特別有用()。

    方法()使用新方法擴展現有類型(不更改類型的定義),使靜態方法感覺像實例方法。LINQ 的查詢運算符作為擴展方法實現。

    ()為編寫 LINQ 查詢提供了更高級別的語法,在處理多個序列或范圍變量時,該語法可以簡單得多。

    ()是微型代碼文檔對象模型 (DOM),用于描述分配給特殊類型 Expression<TDelegate> 的 lambda 表達式。表達式樹使 LINQ 查詢可以遠程執行(例如,在數據庫服務器上),因為它們可以在運行時進行內省和轉換(例如,轉換為 SQL 語句)。

    C# 3.0 還添加了自動屬性和分部方法。

    ()通過讓編譯器自動執行該工作來減少編寫屬性的工作,這些屬性只是獲取/設置私有支持字段。()讓自動生成的分部類為手動創作提供可自定義的鉤子,如果不使用,這些鉤子就會“消失”。

    C# 2.0 中的新增功能

    C# 2 中的重大新功能是泛型(第 章)、可為空的值類型( 章)、迭代器()和匿名方法(lambda 表達式的前身)。這些功能為在 C# 3 中引入 LINQ 鋪平了道路。

    C# 2 還添加了對分部類、靜態類以及大量次要和雜項功能(如命名空間別名限定符、友元程序集和固定大小緩沖區)的支持。

    泛型的引入需要新的 CLR (CLR 2.0),因為泛型在運行時保持完整類型保真度。

    IT之家 6 月 14 日消息,微軟近日邀請 Release Preview 通道的 Windows Insider 項目成員,通過安裝 KB5011048 更新,測試最新發布的 .NET Framework 4.8.1。

    微軟本次發布的 KB5011048 更新特別適用于以下版本:

    • Win11 Version 21H2(初代版本)

    • Win10 Version 21H2(LTSC)

    • Win10 Version 22H2

    IT之家注:微軟官方今天宣布停止對 Win10 Version 21H2 的支持,因此這是該版本 Win10 可以升級使用的 .NET Framework 最后一個版本。

    微軟于 2022 年 8 月宣布了.NET Framework 4.8.1 更新的主要功能,其中最大的亮點在于為 Win11 設備提供 Arm64 原生支持。

網站首頁   |    關于我們   |    公司新聞   |    產品方案   |    用戶案例   |    售后服務   |    合作伙伴   |    人才招聘   |   

友情鏈接: 餐飲加盟

地址:北京市海淀區    電話:010-     郵箱:@126.com

備案號:冀ICP備2024067069號-3 北京科技有限公司版權所有