C# 9 新特性 —— 增強的模式匹配

WeihanLi發表於2021-01-03

C# 9 新特性 —— 增強的模式匹配

Intro

C# 9 中進一步增強了模式匹配的用法,使得模式匹配更為強大,我們一起來了解一下吧

Sample

C# 9 中增強了模式匹配的用法,增加了 and/or/not 操作符,而且可以直接判斷屬性,來看一下下面的這個示例:

var person = new Person();

// or
// string.IsNullOrEmpty(person.Description)
if (person.Description is null or { Length: 0 })
{
    Console.WriteLine($"{nameof(person.Description)} is IsNullOrEmpty");
}

// and
// !string.IsNullOrEmpty(person.Name)
if (person.Name is not null and { Length: > 0 })
{
    if (person.Name[0] is (>= 'a' and <= 'z') or (>= 'A' and <= 'Z') or '.')
    {
    }
}

// not
if (person.Name is not null)
{
}

這裡的程式碼使用 DnSpy 反編譯之後的程式碼是下面這樣的:

Person person = new Person();
string text = person.Description;
bool flag = text == null || text.Length == 0;
if (flag)
{
    Console.WriteLine("Description is IsNullOrEmpty");
}
text = person.Name;
bool flag2 = text != null && text.Length > 0;
if (flag2)
{
    char c = person.Name[0];
    if (c >= 'a')
    {
        if (c > 'z')
        {
            goto IL_8B;
        }
    }
    else if (c >= 'A')
    {
        if (c > 'Z')
        {
            goto IL_8B;
        }
    }
    else if (c != ',' && c != '.')
    {
        goto IL_8B;
    }
    bool flag3 = true;
    goto IL_8E;
    IL_8B:
    flag3 = false;
    IL_8E:
    bool flag4 = flag3;
    if (flag4)
    {
    }
}
bool flag5 = person.Name != null;
if (flag5)
{
}

Switch

這不僅適用於 is 也可以在 switch 中使用

switch (person.Age)
{
    case >= 0 and <= 3:
        Console.WriteLine("baby");
        break;

    case > 3 and < 14:
        Console.WriteLine("child");
        break;

    case > 14 and < 22:
        Console.WriteLine("youth");
        break;

    case > 22 and < 60:
        Console.WriteLine("Adult");
        break;

    case >= 60 and <= 500:
        Console.WriteLine("Old man");
        break;

    case > 500:
        Console.WriteLine("monster");
        break;
}

反編譯後的程式碼:

int age = person.Age;
int num = age;
if (num < 22)
{
    if (num < 14)
    {
        if (num >= 0)
        {
            if (num > 3)
            {
                Console.WriteLine("child");
            }
            else
            {
                Console.WriteLine("baby");
            }
        }
    }
    else if (num > 14)
    {
        Console.WriteLine("youth");
    }
}
else if (num < 60)
{
    if (num > 22)
    {
        Console.WriteLine("Adult");
    }
}
else if (num > 500)
{
    Console.WriteLine("monster");
}
else
{
    Console.WriteLine("Old man");
}

More

可以看到有些情況下可以簡化不少程式碼,尤其是 if 分支比較多的情況下使用上面 switch 這樣的寫法會清晰很多

但是如果只是 string.IsNullOrEmpty 這種程式碼最好還是不要寫得這麼騷了,小心要被同事吐槽了

炫技需謹慎,小心被 ...

Reference

相關文章