當前位置: 妍妍網 > 碼農

C# 12 中新增的幾大功能你都知道嗎?

2024-04-23碼農

前言

轉眼之間C#都已經更新到了12了,那麽C# 12 中新增的八大功能大家都了解過嗎?今天我們來簡單講解一下C# 12 中的八大新增功能。

  • 詳細功能介紹請閱讀微軟官方文件:https://learn.microsoft.com/zh-cn/dotnet/csharp/whats-new/csharp-12

  • 同學們可以使用最新的 Visual Studio 2022 版本或 .NET 8 SDK 嘗試這些功能。

    拾遺補漏合集

    在這個快速發展的技術世界中,時常會有一些重要的知識點、資訊或細節被忽略或遺漏。【C#/.NET/.NET Core拾遺補漏】專欄我們將探討一些可能被忽略或遺漏的重要知識點、資訊或細節,以幫助大家更全面地了解這些技術棧的特性和發展方向。

    GitHub開源地址

    https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetStudy.md

    拾遺補漏知識點投稿

    該Issues主要是給各位小夥伴們提供投稿的地方,你有什麽想要學習的C#/.NET/.NET Core相關技術棧或者已學習過且有文章輸出的歡迎在投稿!

    https://github.com/YSGStudyHards/DotNetGuide/issues/37

    一、主建構函式

    在 Visual Studio 2022 版本 17.6 預覽版 2 中引入。

    從 C# 12 開始,可以在類和結構中聲明主建構函式。主建構函式參數都在類的整個主體的範圍內。為了確保顯式分配所有主建構函式參數,所有顯式聲明的建構函式都必須使用 this() 語法呼叫主建構函式。將主建構函式添加到 class 可防止編譯器聲明隱式無參數建構函式。在 struct 中,隱式無參數建構函式初始化所有欄位,包括 0 位模式的主建構函式參數。

    主建構函式參數的最常見用途包括:

  • 作為 base() 建構函式呼叫的參數。

  • 初始化成員欄位或內容。

  • 參照例項成員中的建構函式參數。

  • 程式碼範例

    將任何參數放在型別名稱後面的括弧中:

    public class NameParameter(string name)
    {
    public string Name => name;
    }

    以下程式碼初始化從主建構函式參數計算的兩個唯讀內容:

    public readonly struct Distance(double dx, double dy)
    {
    public readonly double Magnitude { get; } = Math.Sqrt(dx * dx + dy * dy);
    public readonly double Direction { get; } = Math.Atan2(dy, dx);
    }

    二、集合運算式

    在 Visual Studio 2022 版本 17.7 預覽版 5 中引入。

    集合運算式引入了一種新的簡潔語法,用於建立常用集合值。可以使用展開運算子(..)將其他集合行內到這些值中。

    下面的範例展示了集合運算式的用法:

    // Create an array
    int[] array = [55, 99, 100, 33];
    // Create a list
    List<string> list = ["one""two""three""five""追逐時光者"];
    // Create a span
    Span<char> c = ['a''b''c''d''e''f''h''i''k'];
    // Create a jagged 2D array
    int[][] two2D = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [88, 8, 9]];

    展開運算子(..)範例程式碼:

    展開運算子(集合運算式中的 ..)可將其參數替換為該集合中的元素。參數必須是集合型別。以下範例演示了展開運算子的工作原理:

    int[] item0 = [88, 2, 3];
    int[] item1 = [22, 5, 6];
    int[] item2 = [7, 99, 9];
    int[] single = [.. item0, .. item1, .. item2];
    foreach (var element in single)
    {
    Console.Write($"{element}, ");
    }

    沒有 .. 會有異常:

    正常輸出:

    三、行內陣列

    在 Visual Studio 2022 版本 17.7 預覽版 3 中引入。

    執行時團隊和其他庫作者使用行內陣列來提高應用程式的效能。透過行內陣列,開發人員可以在結構型別中建立固定大小的陣列。具有行內緩沖區的結構體應具有與不安全固定大小緩沖區類似的效能特性。

    行內陣列的聲明與下面的結構類似:

    [System.Runtime.CompilerServices.InlineArray(20)]
    public struct Buffer
    {
    private int _element0;
    }

    你可以像使用其他陣列一樣使用它們:

    public static void Test()
    {
    var buffer = new Buffer();
    for (int i = 0; i < 20; i++)
    {
    buffer[i] = i;
    }
    foreach (var i in buffer)
    {
    Console.WriteLine(i);
    }
    }

    四、Lambda 運算式中的可選參數

    在 Visual Studio 2022 版本 17.5 預覽版 2 中引入。

    可以為 Lambda 運算式的參數定義預設值。語法和規則與將參數的預設值添加到任何方法或本地函式相同。

    如果 lambda 運算式只有一個輸入參數,則括弧是可選的:

    Func<double, double> cube = x => x * x * x;

    兩個或更多輸入參數使用逗號加以分隔:

    Func<int, int, bool> testForEquality = (x, y) => x == y;

    可以顯式指定型別,如下面的範例所示:

    註意:輸入參數型別必須全部為顯式或全部為隱式;否則,便會生成 CS0748 編譯器錯誤!!

    Func<int, string, bool> isTooLong = (int x, string s) => s.Length > x;

    五、ref readonly參數

    在 Visual Studio 2022 版本 17.8 預覽版 2 中引入。

    ref readonly修飾詞表示方法希望參數是一個變量,而不是一個非變量的運算式。不是變量的運算式包括常量、方法返回值和內容。如果參數不是變量,編譯器會發出警告。

    六、任何型別的別名

    在 Visual Studio 2022 版本 17.6 預覽版 3 中引入。

    可以使用 using alias 指令來別名任何型別,而不僅僅是命名型別。也就是說,你可以為元組型別、陣列型別、指標型別或其他不安全型別建立語意別名。

    使用 using 關鍵字為元組型別建立別名,並進行呼叫:

    using PointTest = (int x, int y);
    namespace Csharp12
    {
    internal class class1
    {
    public static void Test()
    {
    PointTest point = (10, 20);
    Console.WriteLine($"Point coordinates: X={point.Item1}, Y={point.Item2}");
    }
    }
    }

    七、Experimental內容

    在 Visual Studio 2022 版本 17.7 預覽版 3 中引入。

  • 可以使用 System.Diagnostics.CodeAnalysis.ExperimentalAttribute 來標記型別、方法或程式集,以指示實驗性特征。如果存取使用 ExperimentalAttribute 註釋的方法或型別,編譯器將發出警告。用 Experimental 特性標記的程式集中包含的所有型別都是實驗性的。

  • 範例程式碼:

    namespace Csharp12
    {
    [AttributeUsage(System.AttributeTargets.Assembly | System.AttributeTargets. class | System.AttributeTargets.Constructor | System.AttributeTargets.Delegate | System.AttributeTargets.Enum | System.AttributeTargets.Event | System.AttributeTargets.Field | System.AttributeTargets.Interface | System.AttributeTargets.Method | System.AttributeTargets.Module | System.AttributeTargets.Property | System.AttributeTargets.Struct)]
    public class ExperimentalAttribute : Attribute
    {
    public ExperimentalAttribute()
    {
    }
    }
    [Experimental]
    public class Experimental class
    {
    public void DoSomething()
    {
    Console.WriteLine("Doing something experimental...");
    }
    }
    internal class class1
    {
    public static void Test()
    {
    Experimental class exp = new Experimental class();
    exp.DoSomething();
    }
    }
    }

    八、攔截器

    預覽功能在 Visual Studio 2022 版本 17.7 預覽版 3 中引入。

    攔截器是一種方法,該方法可以在編譯時以聲明方式將對可攔截方法的呼叫替換為對其自身的呼叫。透過讓攔截器聲明所攔截呼叫的源位置,可以進行這種替換。攔截器可以向編譯中(例如在源生成器中)添加新程式碼,從而提供更改現有程式碼語意的有限能力。

    註意:攔截器是一項試驗性功能,在 C# 12 的預覽模式下提供。在將來的版本中,該功能可能會發生中斷性變更或被刪除。因此,不建議將其用於生產或已釋出的應用程式。

    要使用攔截器,使用者計畫必須指定 <InterceptorsPreviewNamespaces> 內容。這是允許包含攔截器的名稱空間列表。

    <InterceptorsPreviewNamespaces>$(InterceptorsPreviewNamespaces);Microsoft.AspNetCore.Http.Generated;MyLibrary.Generated</InterceptorsPreviewNamespaces>


  • 學習是一個永無止境的過程,你知道的越多,你不知道的也會越多,在有限的時間內堅持每天多學一點,你一定能成為你想要成為的那個人。不積跬步無以至千裏,不積小流無以成江河!!!

    See you next good day