这些C#新功能,让你的C#代码更加简洁优雅。

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

好了,今天就简单介绍到这里,咱们下期再见。更多资料请关注微信公众号爱游戏爱编程
爱游戏爱编程

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李公子lm

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值