概述
C#9.0中的switch 匹配模式引入了许多新特性,其中一些特性是C#8.0中不存在的,比如以下特性:
- 关系模式:可以使用关系运算符
- 模式匹配+逻辑模式:可以使用模式匹配+逻辑模式(如and、or)来组合多个模式
- 模式匹配+关系模式:可以使用模式匹配+关系运算符(如<、>、<=、>=、==、!=)
- 默认的匹配不必使用丢弃“_”来实现
下面我们举例说明一下这些特性:
示例
下面我将使用dotnet cli 创建一个dotnet 6.0的项目。
环境信息
Platform:Windows 11
Dotnet SDK:6.0
IDE:VS Code
首先我们按照以下步骤创建项目:
步骤一:创建项目文件夹
mkdir CSharp9.ChapterSwitch.Sample
cd CSharp9.ChapterSwitch.Sample
步骤二:创建项目文件
dotnet new sln -n CSharp9.ChapterSwitch.Sample
mkdir src
cd src
步骤三:创建类库以及控制台
dotnet new console -n CSharp9.ChapterSwitch.Console --framework net6.0
dotnet new classlib -n CSharp9.ChapterSwitch.Models --framework net6.0
步骤四:将类库以及控制台添加到项目上
cd ..
dotnet sln add src/CSharp9.ChapterSwitch.Console/CSharp9.ChapterSwitch.Console.csproj
dotnet sln add src/CSharp9.ChapterSwitch.Models/CSharp9.ChapterSwitch.Models.csproj
dotnet add src/CSharp9.ChapterSwitch.Console/CSharp9.ChapterSwitch.Console.csproj reference src/CSharp9.ChapterSwitch.Models/CSharp9.ChapterSwitch.Models.csproj
步骤五:示例代码
1、Models 类库代码
在Models类库中,按照以下代码片段添加相关的类文件,请注意类的命名空间
fragment 1
namespace CSharp9.ChapterSwitch.Models;
public class Electronic
{
public double Price { get; set; }
public string Name { get; set; }
}
namespace CSharp9.ChapterSwitch.Models;
public class MobilePhone : Electronic
{
}
namespace CSharp9.ChapterSwitch.Models;
public class Camera : Electronic
{
public double Pixel { get; set; }
}
namespace CSharp9.ChapterSwitch.Models;
public class Computer : Electronic
{
public int LightingInterface { get; set; }
}
2、Console 代码
在Console控制台的Program中添加 code fragment2的代码片段
fragment 2
using CSharp9.ChapterSwitch.Models;
using System;
class Program
{
static void Main(string[] args)
{
SwitchExpression();
}
static void SwitchExpression()
{
Electronic[] electronics =
{
new MobilePhone{Name="XIAOMI5",Price=5000},
new MobilePhone{Name="IPhone13Pro",Price=9000},
new MobilePhone{Name="HUAWEIMate50Pro",Price=7000},
new MobilePhone{Name="HUAWEIP50Pro",Price=8000},
new Camera{Name="Canon80D",Price=7000,Pixel=12000_000},
new Computer{Name="DELLXPS7590",Price=8600,LightingInterface=1},
new Computer{Name="DELLXPS9360",Price=12000,LightingInterface=3}
};
foreach (var electronic in electronics)
{
{
//c#8.0
var desc = electronic switch
{
MobilePhone s => s.Price switch
{
double a when a <= 5000 => "Cost performance electronic",
double a when a <= 7000 => "Slightly expensive electronic",
double a when a <= 9000 => "Light luxury electronic",
_ => "Other"
},
Camera s when s.Price <= 7000 && s.Pixel <= 12000_000 => "Cost performance electronic",
Camera _ => "Other",
Computer s when s.Price <= 7000 && s.LightingInterface >= 1 => "Cost performance electronic",
Computer s when s.Price <= 10000 && s.LightingInterface >= 2 => "Slightly expensive electronic",
Computer s when s.Price <= 12000 && s.LightingInterface >= 3 => "Light luxury electronic",
Computer _ => "Other",
_ => throw new NotImplementedException()
};
Console.WriteLine($"Current electronic is {electronic.Name},price:{electronic.Price:C},is {desc}.");
}
}
Console.Read();
}
}
3、Console 项目设置
fragment 3
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>disable</ImplicitUsings>
<Nullable>disable</Nullable>
<LangVersion>8</LangVersion>
</PropertyGroup>
运行代码:
dotnet run --project src/CSharp9.ChapterSwitch.Console/CSharp9.ChapterSwitch.Console.csproj
如上例,有一个 Electronic父类,Mobile、Camera、Computer分别继承Electronic类,并且每个自类有可能有自己单独的属性,然后在Program中声明一个Electronic数组,并且循环输出信息,循环判断并输出当前电子产品的定位,性价比、稍贵、轻奢品
以上Console中的Program是使用的C#8.0的语法编写Switch的匹配模式,下面我们使用C#9.0的Switch匹配模式新特性来重构这段代码:
4、匹配模式新特性
设置Console.csproj的 LangVersion=9,重构以上Console中代码,重新运行项目
fragment 4
using CSharp9.ChapterSwitch.Models;
using System;
class Program
{
static void Main(string[] args)
{
SwitchExpression();
}
static void SwitchExpression()
{
Electronic[] electronics =
{
new MobilePhone{Name="XIAOMI5",Price=5000},
new MobilePhone{Name="IPhone13Pro",Price=9000},
new MobilePhone{Name="HUAWEIMate50Pro",Price=7000},
new MobilePhone{Name="HUAWEIP50Pro",Price=8000},
new Camera{Name="Canon80D",Price=7000,Pixel=12000_000},
new Computer{Name="DELLXPS7590",Price=8600,LightingInterface=1},
new Computer{Name="DELLXPS9360",Price=12000,LightingInterface=3}
};
Console.WriteLine($"C# 8.0");
foreach (var electronic in electronics)
{
{
//c#8.0
var desc = electronic switch
{
MobilePhone s => s.Price switch
{
double a when a <= 5000 => "Cost performance electronic",
double a when a <= 7000 => "Slightly expensive electronic",
double a when a <= 9000 => "Light luxury electronic",
_ => "Other"
},
Camera s when s.Price <= 7000 && s.Pixel <= 12000_000 => "Cost performance electronic",
Camera _ => "Other",
Computer s when s.Price <= 7000 && s.LightingInterface >= 1 => "Cost performance electronic",
Computer s when s.Price <= 10000 && s.LightingInterface >= 2 => "Slightly expensive electronic",
Computer s when s.Price <= 12000 && s.LightingInterface >= 3 => "Light luxury electronic",
Computer _ => "Other",
_ => throw new NotImplementedException()
};
Console.WriteLine($"Current electronic is {electronic.Name},price:{electronic.Price:C},is {desc}.");
}
};
Console.WriteLine($"C# 9.0 写法1");
foreach (var electronic in electronics)
{
{
// c#9.0 写法1
var desc = electronic switch
{
MobilePhone s => s.Price switch //关系模式
{
<= 5000 => "Cost performance electronic",
<= 7000 => "Slightly expensive electronic",
<= 9000 => "Light luxury electronic",
_ => "Other"
},
Camera { Price: <= 7000, Pixel: <= 12000_000 } => "Cost performance electronic", // 模式变量+关系模式
Camera => "Other",// 无需丢弃"_"
Computer { Price: <= 7000, LightingInterface: >= 1 } => "Cost performance electronic",
Computer { Price: <= 10000, LightingInterface: >= 2 } => "Slightly expensive electronic",
Computer { Price: <= 12000, LightingInterface: >= 3 } => "Light luxury electronic",
Computer => "Other",
_ => throw new NotImplementedException()
};
Console.WriteLine($"Current electronic is {electronic.Name},price:{electronic.Price:C},is {desc}.");
}
};
Console.WriteLine($"C# 9.0 写法2");
foreach (var electronic in electronics)
{
{
// c#9.0 写法2
var desc = electronic switch
{
MobilePhone { Price: <= 5000 } or Camera { Price: <= 7000, Pixel: <= 12000_000 } or Computer { Price: <= 7000, LightingInterface: >= 1 } => "Cost performance electronic",//模式变量+关系模式+逻辑或
MobilePhone s => s.Price switch
{
<= 5000 => "Cost performance electronic",
<= 7000 => "Slightly expensive electronic",
<= 9000 => "Light luxury electronic",
_ => "Other"
},
Camera => "Other",
Computer { Price: <= 10000 } and Computer { LightingInterface: >= 2 } => "Slightly expensive electronic", //模式变量+关系模式+逻辑与
Computer { Price: <= 12000 } and Computer { LightingInterface: >= 3 } => "Light luxury electronic",
Computer => "Other",
_ => throw new NotImplementedException()
};
Console.WriteLine($"Current electronic is {electronic.Name},price:{electronic.Price:C},is {desc}.");
}
}
Console.Read();
}
}
重新运行代码
dotnet run --project src/CSharp9.ChapterSwitch.Console/CSharp9.ChapterSwitch.Console.csproj