C#11新特性整理

Eric zhou發表於2023-01-19

假期中有時間,整理了C#11的各個新特性,簡單分享給大家。

一、使用VSCode新建一個.NET7.0的Console工程

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net7.0</TargetFramework>
    <RootNamespace>_NET7</RootNamespace>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>
</Project>

二、泛型屬性

C # 11為開發人員提供了一種編寫自定義通用屬性的方法。

public class CommonAttribute<T> : Attribute
{
    public T Property {get;set;}

    public CommonAttribute() 
    {
        
    }

    public CommonAttribute(T realvalue) :this()
    {
        Property = realvalue;
    }
}

新建一個類,在屬性上使用這個通用屬性註解。原先是多個屬性註解型別,現在一個泛型屬性就可以搞定了

public class User
{
    [CommonAttribute<int>]
    public int UserID { get; set;}

    [CommonAttribute<string>("defaultValue")]
    public string UserName { get; set;}
}

三、非空校驗

原先在C#10中,可以這麼寫實現引數非空校驗

public User GetUser(string name)
{
    ArgumentNullException.ThrowIfNull(nameof(name));
    // Rest of code
}

在C#11中,原計劃在引數上加2個!就實現了非空校驗,實際測試是不支援的。

error CS8989: 不支援 'parameter null-checking' 功能。

 

 四、字串內的換行符

字串內插的 { 和 } 字元內的文字現在可以跨多個行。 

{ 和 } 標記之間的文字分析為 C#。 允許任何合法 C#(包括換行符)。

使用此功能可以更輕鬆地讀取使用較長 C# 表示式的字串內插,例如模式匹配 switch 表示式或 LINQ 查詢。

五、列表模式匹配

列表模式擴充套件了模式匹配,以匹配列表或陣列中的元素序列。

例如,當 sequence 為陣列或三個整數(1、2 和 3)的列表時,sequence is [1, 2, 3] 為 true

可以使用任何模式(包括常量、型別、屬性和關係模式)來匹配元素。

棄元模式 (_) 匹配任何單個元素,新的範圍模式 (..) 匹配零個或多個元素的任何序列。

寫幾個列子看看:

var l1 = new[] { 1, 2, 3, 4, 5 };
if(l1 is [1, 2, 3, 4, 5] && l1 is [_,_,_,_,5])
{
    Console.WriteLine("List Pattern Matched");
}

 

 上述程式碼中,[_,_,_,_,5] ,可以這麼理解:匹配長度為5且最後一個元素為5的任何集合。

 

 同時,切片模式進一步放大了列表模式的威力。例如,如果需要將任何少於或等於5個元素的集合與最後一個元素5匹配,則可以將上述模式修改為

if (l1 is [.., 5])
{
    Console.WriteLine("List Pattern Matched 3");
}

   這段程式碼中 [..,5] 等同於 l1.Length>=1 && l1[^1]==5.

  除錯輸出:List Pattern Matched 3

   再寫一個Switch模式匹配的例子

var l1 = new[] { 1, 2, 3, 4,5 };
var l2 = new[] { 1, 3, 5 };
var l3 = new[] { 1};
var l4 = new[] { 9 };
var l5 = new[] { 1,6 };

string PatternTest(int[] collection) => collection switch
{
    [1, 2, 3, 4, 5] => "first", // list
    [1, 3, .., 5] => "second", // slice in list
    [1, _] => "third", // list
    [1, ..] => "fourth", //slice in list
    [..] => "fifth" // slice
};

Console.WriteLine(PatternTest(l1));
Console.WriteLine(PatternTest(l2));
Console.WriteLine(PatternTest(l3));
Console.WriteLine(PatternTest(l4));
Console.WriteLine(PatternTest(l5));

實際輸出:

first
second
fourth
fifth
third

 六、原始字串

原始字串是字串的一種新格式。

原始字串可以包含任意文字,包括空格、新行、嵌入引號和其他特殊字元,無需跳脫字元(這個很關鍵、也很簡單)

原始字串以至少三個雙引號 (""") 字元開頭。 它以相同數量的雙引號字元結尾。

通常,原始字串在單個行上使用三個雙引號來開始字串,在另一行上用三個雙引號來結束字串。 左引號之後、右引號之前的換行符不包括在最終內容中。

詳細的示例,可以看前段時間整理的一篇文章。

C#11新特性-Raw string literals原始字串研究、示例

以上是這幾天研究的C#11的新特性。分享給大家。

 

周國慶

2023/1/19

 

相關文章