Skip to content

C# 12 新特性

2023 年 4 月 10 日 C# 12 正式发布

.NET 首席项目经理凯瑟琳在博客中介绍了 C# 12 的一些预览版新功能,这些功能可以在 Visual Studio 17.6 预览版和最新的.NET 8 预览版中体验。

集合表达式

集合表达式引入了新的 terse 语法来创建常见的集合值。 可以使用展开运算符 .. 将其他集合内联到这些值中。

以下示例演示了集合表达式的使用:

c#
// Create an array:
int[] a = [1, 2, 3, 4, 5, 6, 7, 8];

// Create a list:
List<string> b = ["one", "two", "three"];

// Create a span
Span<char> c  = ['a', 'b', 'c', 'd', 'e', 'f', 'h', 'i'];

// Create a jagged 2D array:
int[][] twoD = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];

// Create a jagged 2D array from variables:
int[] row0 = [1, 2, 3];
int[] row1 = [4, 5, 6];
int[] row2 = [7, 8, 9];
int[][] twoDFromVariables = [row0, row1, row2];

展开运算符(集合表达式中的 ..)可将其参数替换为该集合中的元素。 参数必须是集合类型。 以下示例演示了展开运算符的工作原理:

c#
int[] row0 = [1, 2, 3];
int[] row1 = [4, 5, 6];
int[] row2 = [7, 8, 9];
int[] single = [.. row0, .. row1, .. row2];
foreach (var element in single)
{
    Console.Write($"{element}, ");
}
// output:
// 1, 2, 3, 4, 5, 6, 7, 8, 9,

展开运算符的操作数是可以枚举的表达式。 展开运算符可计算枚举表达式的每个元素。

可以在需要元素集合的任何位置使用集合表达式。 它们可以指定集合的初始值,也可以作为参数传递给采用集合类型的方法。

改进的 Switch 表达式

C# 8 中引入了 Switch 表达式,使开发人员可以简洁易读地表达复杂的条件逻辑。C# 12 通过为 switch 表达式引入新的模式匹配语法进一步推进了这一点,使编写富有表现力和简洁的代码变得更加容易。

  • 考虑以下代码片段

    C#
    var result = obj switch
    {
        int i when i > 0 => "Positive",
        int i when i < 0 => "Negative",
        _ => "Zero"
    };
  • 此代码使用 switch 表达式来确定整数是正数、负数还是零。当关键字用于引入必须匹配才能执行相应案例的模式时。在 C# 12 中,我们可以使用新的模式匹配语法进一步简化此代码

    C#
    var result = obj switch
    {
      > 0 => "Positive",
      < 0 => "Negative",
      _ => "Zero"
    };

    这种语法允许我们省略 when 关键字并直接在 switch 表达式中使用关系运算符。

主构造函数

现在可以在任何 classstruct 中创建主构造函数。 主构造函数不再局限于 record 类型。 主构造函数参数都在类的整个主体的范围内。 为了确保显式分配所有主构造函数参数,所有显式声明的构造函数都必须使用 this() 语法调用主构造函数。 将主构造函数添加到 class 可防止编译器声明隐式无参数构造函数。 在 struct 中,隐式无参数构造函数初始化所有字段,包括 0 位模式的主构造函数参数。

属性和方法改进

C# 12 对属性和方法进行了多项改进,使其更具表现力和灵活性。

方法扩展

方法扩展允许我们在不修改类的情况下向现有类添加新方法。在 C# 12 中,我们现在可以使用扩展方法向接口添加方法,从而更容易编写可重用代码。

C#
interface MyInterface
{
    void Method1();
}

static class MyExtensions
{
    public static void Method2(this MyInterface obj)
    {
        // Method implementation
    }
}

class MyClass: MyInterface
{
    public void Method1()
    {
        // Method implementation
    }
}

var obj = new MyClass();
obj.Method1();
obj.Method2();

Lambda 改进

Lambda 是 C# 中的一个强大功能,它使我们能够编写简洁而富有表现力的代码。在 C# 12 中,通过引入多项改进,lambda 变得更好。

在 C# 12 中,我们现在可以在 lambda 中使用隐式类型,使它们更加简洁和可读。

C#
List<int> numbers = new() { 1, 2, 3, 4, 5 };

var evenNumbers = numbers.Where(n => n % 2 == 0);

简化参数空值检查

下面是一个使用 C# 12 预览版的参数空值检查新功能简化参数空值检查的示例

C#
public void ExampleMethod(string? parameter1, string? parameter2)
{
    // Parameter null checking using the new '!' operator
    parameter1! ?? throw new ArgumentNullException(nameof(parameter1));
    parameter2! ?? throw new ArgumentNullException(nameof(parameter2));

    // Rest of the method logic goes here...
}

在上面的例子中,!运算符用于在继续方法逻辑的其余部分之前对 parameter1 和 parameter2 参数进行空检查。如果任一参数为 null,则抛出 ArgumentNullException 并将参数名称作为消息。

你觉得这篇文章怎么样?
  • 0
  • 0
  • 0
  • 0
  • 0
  • 0
评论
  • 按正序
  • 按倒序
  • 按热度