C#8.0 和9.0已经更新了一段时间了,里面新增了一些功能,可以让你的C#代码更加优雅,目前.NET “.NET Core 3.x”和“.NET Standard 2.1”支持 C# 8.0,.NET5 支持C#9.0。
switch 表达式
通常情况下,switch 语句在其每个 case 块中生成一个值。 借助 Switch 表达式,可以使用更简洁的表达式语法。 只有些许重复的 case 和 break 关键字和大括号。
先这里定义个枚举。
public enum Rainbow
{
Red,
Orange,
Yellow,
Green,
Blue,
Indigo,
Violet
}
经典的Switch语句
public static RGBColor FromRainbowClassic(Rainbow colorBand)
{
switch (colorBand)
{
case Rainbow.Red:
return new RGBColor(0xFF, 0x00, 0x00);
case Rainbow.Orange:
return new RGBColor(0xFF, 0x7F, 0x00);
case Rainbow.Yellow:
return new RGBColor(0xFF, 0xFF, 0x00);
case Rainbow.Green:
return new RGBColor(0x00, 0xFF, 0x00);
case Rainbow.Blue:
return new RGBColor(0x00, 0x00, 0xFF);
case Rainbow.Indigo:
return new RGBColor(0x4B, 0x00, 0x82);
case Rainbow.Violet:
return new RGBColor(0x94, 0x00, 0xD3);
default:
throw new ArgumentException(message: "invalid enum value", paramName: nameof(colorBand));
};
}
switch表达式写法。
public static RGBColor FromRainbow(Rainbow colorBand) =>
colorBand switch
{
Rainbow.Red => new RGBColor(0xFF, 0x00, 0x00),
Rainbow.Orange => new RGBColor(0xFF, 0x7F, 0x00),
Rainbow.Yellow => new RGBColor(0xFF, 0xFF, 0x00),
Rainbow.Green => new RGBColor(0x00, 0xFF, 0x00),
Rainbow.Blue => new RGBColor(0x00, 0x00, 0xFF),
Rainbow.Indigo => new RGBColor(0x4B, 0x00, 0x82),
Rainbow.Violet => new RGBColor(0x94, 0x00, 0xD3),
_ => throw new ArgumentException(message: "invalid enum value", paramName: nameof(colorBand)),
};
瞬间简洁了好多呢。
using 声明
using 声明是前面带 using 关键字的变量声明。 它指示编译器声明的变量应在封闭范围的末尾进行处理。
经典的using使用,必须把所写的代码包括在大括号内部。
static int WriteLinesToFile(IEnumerable<string> lines)
{
using (var file = new System.IO.StreamWriter("WriteLines2.txt"))
{
int skippedLines = 0;
foreach (string line in lines)
{
if (!line.Contains("Second"))
{
file.WriteLine(line);
}
else
{
skippedLines++;
}
}
return skippedLines;
} // file is disposed here
}
新的写法。可以去掉大括号。
static int WriteLinesToFile(IEnumerable<string> lines)
{
using var file = new System.IO.StreamWriter("WriteLines2.txt");
int skippedLines = 0;
foreach (string line in lines)
{
if (!line.Contains("Second"))
{
file.WriteLine(line);
}
else
{
skippedLines++;
}
}
// Notice how skippedLines is in scope here.
return skippedLines;
// file is disposed here
}
嗯,这个和之前变化不大。
索引和范围
索引和范围为访问序列中的单个元素或范围提供了简洁的语法。
此语言支持依赖于两个新类型和两个新运算符:
- System.Index 表示一个序列索引。
- 来自末尾运算符 ^ 的索引,指定一个索引与序列末尾相关。
- System.Range 表示序列的子范围。
- 范围运算符 …,用于指定范围的开始和末尾,就像操作数一样。
举例,定一个数组。
var words = new string[]
{
// index from start index from end
"The", // 0 ^9
"quick", // 1 ^8
"brown", // 2 ^7
"fox", // 3 ^6
"jumped", // 4 ^5
"over", // 5 ^4
"the", // 6 ^3
"lazy", // 7 ^2
"dog" // 8 ^1
}; // 9 (or words.Length) ^0
可以使用 ^1 索引检索最后一个词:
Console.WriteLine($"The last word is {words[^1]}");
// writes "dog"
以下代码创建了一个包含单词“quick”、“brown”和“fox”的子范围。 它包括 words[1] 到 words[3]。 元素 words[4] 不在该范围内。
var quickBrownFox = words[1..4];
以下代码使用“lazy”和“dog”创建一个子范围。 它包括 words[^2] 和 words[^1]。 末尾索引 words[^0] 不包括在内:
var lazyDog = words[^2..^0];
下面的示例为开始和/或结束创建了开放范围:
var allWords = words[..]; // contains "The" through "dog".
var firstPhrase = words[..4]; // contains "The" through "fox"
var lastPhrase = words[6..]; // contains "the", "lazy" and "dog"
三元表达式
对于返回值为bool类型的三元表达式,只需要写比较语句即可。
经典写法。
int number = 10;
bool flag= number >1?true:false;
简洁写法
int number = 10;
bool flag= number >1;
new()的省略用法
在 C# 9.0 中,已知创建对象的类型时,可在 new 表达式中省略该类型。 最常见的用法是在字段声明中:
private List<WeatherObservation> _observations = new();
初始化对象时,可以这样写了。
WeatherStation station = new() { Location = "Seattle, WA" };
模式匹配增强功能
C# 9 包括新的模式匹配改进:
- 类型模式要求在变量是一种类型时匹配
- 带圆括号的模式强制或强调模式组合的优先级
- 联合 and 模式要求两个模式都匹配
- 析取 or 模式要求任一模式匹配
- 求反 not 模式要求模式不匹配
- 关系模式要求输入小于、大于、小于等于或大于等于给定常数。
例如下面的用法。
public static bool IsLetter(this char c) =>
c is >= 'a' and <= 'z' or >= 'A' and <= 'Z';
或者这种。
if (e is not null)
{
// ...
}
这些模式中的任何一种都可在允许使用模式的任何上下文中使用:is 模式表达式、switch 表达式、嵌套模式以及 switch 语句的 case 标签的模式。
参考资料:
https://docs.microsoft.com/zh-cn/dotnet/csharp/whats-new/csharp-9
https://docs.microsoft.com/zh-cn/dotnet/csharp/whats-new/csharp-8
好了,今天就简单介绍到这里,咱们下期再见。更多资料请关注微信公众号爱游戏爱编程
。