前言
嗨,大家好!
前兩天,我們?cè)凇?/span>使用 C# 模式匹配,告別難以維護(hù)的 if-else 語(yǔ)句》一文中一起探討了 C# 模式匹配在我們?nèi)粘i_(kāi)發(fā)任務(wù)中的應(yīng)用,引發(fā)了很多小伙伴的熱烈討論。
今天,我總結(jié)了模式匹配 10 個(gè)常用方法,我們繼續(xù)一起深入挖掘 C# 模式匹配的魅力,看看它如何幫助我們編寫(xiě)更簡(jiǎn)潔、更易讀且更具表現(xiàn)力的代碼!
一些澄清
有的小伙伴以為有了模式匹配,就可以徹底拋棄if-else
語(yǔ)句了。
其實(shí)不然,模式匹配本質(zhì)上也是一種高級(jí)的條件判斷方式,它提供了一種更靈活的方式來(lái)進(jìn)行條件判斷,特別是新的switch
表達(dá)式語(yǔ)法,可以更靈活地控制邏輯,簡(jiǎn)化復(fù)雜邏輯的判斷,編寫(xiě)出更具表現(xiàn)力和功能強(qiáng)大的代碼。
基本語(yǔ)法
1. 使用 is 關(guān)鍵字進(jìn)行類(lèi)型模式匹配
if (obj is string str)
{
Console.WriteLine($"String length is: {str.Length}");
}
2. 在 switch 語(yǔ)句中使用模式匹配
從 C# 8.0 開(kāi)始,switch
語(yǔ)句被增強(qiáng)為switch
表達(dá)式,允許更簡(jiǎn)潔的語(yǔ)法(特別是結(jié)合when
子句),并且可以直接返回值,可以替代傳統(tǒng)的條件語(yǔ)句,提高代碼的可讀性和簡(jiǎn)潔性。
普通switch
表達(dá)式:
var time = DateTime.Now;
switch (time)
{
case { Year: 2023 or 2024, Month: <= 12, Day: 12 } t:
Console.WriteLine($"the first day of every month in the first half of 2020 and 2021");
break;
}
在switch
表達(dá)式中直接返回值的簡(jiǎn)潔寫(xiě)法:
string GetAnimalSound(Animal animal) => animal switch
{
Dog => "Woof!",
Cat => "Meow!",
_ => "Unknown sound"
};
10 常用的使用方法
1. 類(lèi)型模式
檢查一個(gè)表達(dá)式是否屬于特定類(lèi)型,并且可以選擇性地將該表達(dá)式轉(zhuǎn)換為該類(lèi)型。
object obj = "Hello, World!";
if (obj is string str)
{
Console.WriteLine($"String length: {str.Length}");
}
2. 常量模式
檢查一個(gè)表達(dá)式的值是否等于某個(gè)常量,這是最簡(jiǎn)單的模式匹配形式。
object value = 42;
switch (value)
{
case 42:
Console.WriteLine("The answer to life, the universe, and everything.");
break;
default:
Console.WriteLine("Just another number.");
break;
}
3. 屬性模式
允許你根據(jù)對(duì)象的屬性值進(jìn)行匹配,這在處理復(fù)雜對(duì)象時(shí)非常有用
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
Person person = new() { Name = "Alice", Age = 30 };
switch (person)
{
case Person p when p.Age < 18:
Console.WriteLine($"{p.Name} is a minor.");
break;
case Person p when p.Age >= 18 && p.Age < 65:
Console.WriteLine($"{p.Name} is an adult.");
break;
case Person p when p.Age >= 65:
Console.WriteLine($"{p.Name} is a senior citizen.");
break;
}
4. 關(guān)系模式
使用關(guān)系運(yùn)算符(如<
,>
)進(jìn)行匹配
object value = 7;
if (value is int a && a > 6)
{
Console.WriteLine(a);
}
5. 邏輯模式
使用邏輯運(yùn)算符(如and
,or
,not
)組合多個(gè)模式
object value = 7;
if (value is int a && a > 6 && a < 10)
{
Console.WriteLine(a);
}
6. 元組模式
允許你對(duì)元組中的元素進(jìn)行解構(gòu)和匹配
var point = (x: 10, y: 20);
switch (point)
{
case (0, 0):
Console.WriteLine("Origin");
break;
case (var x, 0):
Console.WriteLine($"On X-axis at ({x}, 0)");
break;
case (0, var y):
Console.WriteLine($"On Y-axis at (0, {y})");
break;
case (var x, var y):
Console.WriteLine($"Point at ({x}, {y})");
break;
}
7. 位置模式
位置模式可以對(duì)對(duì)象的屬性進(jìn)行檢查和匹配
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
void CheckPerson(Person person)
{
switch (person)
{
case { Name: "Alice", Age: 30 }:
Console.WriteLine("Found Alice, Age 30");
break;
default:
// 如果有其他情況需要處理,可以在這里添加邏輯
break;
}
}
8. 遞歸模式
C# 8.0 引入了對(duì)更復(fù)雜對(duì)象結(jié)構(gòu)的模式匹配,允許嵌套匹配。
public class Animal
{
public string Type { get; set; }
}
public class Dog : Animal
{
public string Breed { get; set; }
}
void CheckAnimal(Animal animal)
{
switch (animal)
{
case Dog { Breed: "Labrador" }:
Console.WriteLine("It's a Labrador!");
break;
}
}
9. 列表模式
列表模式允許將數(shù)組或列表與一系列模式進(jìn)行匹配。
列表模式的語(yǔ)法是用方括號(hào)括起來(lái)的值。
例如:
int[] numbers = { 1, 2, 3 };
// 使用列表模式來(lái)匹配一個(gè)整數(shù)數(shù)組
Console.WriteLine(numbers is [1, 2, 3]); // True
事實(shí)上,列表模式可以使用任何模式,包括常量、類(lèi)型、屬性和關(guān)系模式。
例如:
List<int> numbers = new() { 1, 2, 3 };
// 使用棄元模式(_)和 var 模式來(lái)匹配數(shù)組中的元素
if (numbers is [var first, _, _])
{
Console.WriteLine($"列表中的第 1 個(gè)元素是 {first}。");
}
// 輸出:
// 列表中的第 1 個(gè)元素是 1。
10. 切片模式
切片模式允許匹配零個(gè)或多個(gè)元素的序列。
切片模式的語(yǔ)法是兩個(gè)點(diǎn)(..)。
例如,以下代碼展示了如何使用切片模式來(lái)匹配數(shù)組中的元素:
void MatchMessage(string message)
{
var result = message is ['a' or 'A', .. var s, 'a' or 'A']
? $"Message {message} matches; inner part is {s}."
: $"Message {message} doesn't match.";
Console.WriteLine(result);
}
MatchMessage("aBBA"); // 輸出: Message aBBA matches; inner part is BB.
MatchMessage("apron"); // 輸出: Message apron doesn't match.
PS:可以利用切片模式的特點(diǎn)丟棄或捕獲零個(gè)或多個(gè)元素。例如:
void List_Pattern(object[] num)
{
int a = 0;
// 匹配數(shù)組中的前三個(gè)元素,并將第三個(gè)元素賦值給變量third
if (num is [1, int, var third, _])
{
Console.WriteLine("第一個(gè)為整數(shù)1");
Console.WriteLine("第二個(gè)為整數(shù)類(lèi)型");
Console.WriteLine($"第三個(gè)為{third.ToString()}");
Console.WriteLine("第四個(gè)隨便");
}
}
總結(jié)
總而言之,C# 里的模式匹配功能強(qiáng)大且靈活,允許我們輕松地進(jìn)行條件判斷和數(shù)據(jù)解構(gòu),對(duì)于更復(fù)雜的數(shù)據(jù)結(jié)構(gòu)和邏輯流程,模式匹配也提供了非常強(qiáng)大的支持,不妨在你的項(xiàng)目中應(yīng)用起來(lái),相信不會(huì)讓你失望的!
該文章在 2024/12/13 9:13:49 編輯過(guò)