发布于 2026-01-06 3 阅读
0

C# 11 新功能泄露!微软送出的最佳圣诞礼物?

C# 11 新功能泄露!微软送出的最佳圣诞礼物?

2021年已经接近尾声(我还在回味2019年),我想我们都会同意,这一年非常充实而忙碌,比如发布了C# 10、.NET 6等等。但是,C# 11的功能怎么这么快就要发布了?微软不是一个月前才发布了C# 10吗?

微软真的在为所有 C# 开发者准备一份惊喜大礼吗?C# 11 作为今年的圣诞礼物?如果这是真的,让我们提前看看 C# 11 的新功能吧。

C# 10 是微软 C# 编程语言的最新版本。它旨在成为一种易于初学者学习的编程语言,注重简洁性、可读性和高效性。

我之前已经介绍过 C# 10 的一些特性,但为了唤起大家的记忆,C# 10 的一些特性包括:

  • 文件作用域命名空间声明
  • 全局使用指令
  • 循环结构
  • 记录结构
  • 处理
  • 改进 lambda 表达式
  • 标准化类型和数据结构

这些在 C# 10 中实现的特性大大提高了应用程序的性能,从而降低了开发成本和时间。

但让我们来看看 C# 11 最近的发展情况,以及它为何如此受关注。


C# 11 有什么新内容?

众所周知,微软在11月初发布了C#10,带来了许多创新特性,使C#成为一门更加通用的语言。但就在几天前,关于C#11的传闻开始在网络上流传,其可能的特性已在Reddit的一个帖子中公布,该帖子还提到了微软官方GitHub上的更新日志。这些特性看起来非常有趣,让我们来分析一下:


通用属性

这是GitHub 上最早的 C# 问题之一中讨论的第一个特性。微软在开发这个很有前景的特性时遇到了一些问题,因为它在最后时刻与其他工具存在兼容性问题(包括崩溃和编译问题)。因此,微软并没有在 C# 10 中正式发布该特性,而是以预览版的形式推出。让我们来看看它是如何工作的:

正如Ashmind在他的提案中所解释的那样

“对于某些TypeConverterAttribute用于引用类型的属性(例如),目前的用法如下:”

[TypeConverter(typeof(X))]
Enter fullscreen mode Exit fullscreen mode

他认为,这个问题有两个缺点:

  • 您无法保证类型符合属性的要求——例如,构造函数为空或继承自某个类型TypeConverter

  • 语法有点冗长。

Ashmind建议应该支持通用属性,包括所有通用约束。以下是一个示例:

[TypeConverter<X>]
Enter fullscreen mode Exit fullscreen mode

你提出的这个方案非常好,它有几个优点。用他自己的话说:

  • 支持类型引用属性中的类型约束。

  • 更简洁的语法。

  • 据我所知,IL 已经支持通用属性。


字段关键词

这是许多 C# 开发人员最喜欢的功能。我们一直在 C# 10 的预览版中分析这个功能,但由于时间不足,它尚未正式发布(据微软称)。不过,他们似乎确信会在 C# 11 中发布该功能,届时我们将能够热情地使用它。

为了理解字段关键字,我将采用该提案的创建者Lachbaer的解释,因为在我看来,这是理解字段关键字的最佳方式:

“创建可以拥有 getter 和 setter 的自动属性。这些属性可以通过field关键字访问自动创建的后备字段,该关键字的作用类似于变量,就像 value 属性的作用一样。”

下面,拉赫贝尔将通过一个非常简单的例子来解释这个功能的工作原理:

在下列情况下会创建具有自动支持字段的半自动属性:

  • 必须有一个“get;或”set;语句,
  • 该属性有一个初始化器

约束

public string PropertyConstraint {
    get;
    set => field = value ?? throw new ArgumentNullException();
} = "";
Enter fullscreen mode Exit fullscreen mode

setter 定义了一个约束。field表示自动创建的后备字段。与自动属性一样,后备字段由 . 初始化= ""

Getter 逻辑

public T PropertyAssertedGet {
    int getCounter = 0;   // property scoped field #133
    get 
    {
        getCounter++;
        Debug.Assert (getCounter <= 3,
              "In my code this prop is only called 3 times, somethings terribly wrong.");
        return field;
    }
    set;
}
Enter fullscreen mode Exit fullscreen mode

活动筹款

public T PropertyEvent {
    get;
    set
    {
        var oldValue = field;
        OnPropertyChanging(
            new PropertyChangingEventArgs(/* current value */ oldValue, /* new value */ value));
        field = value;
        OnPropertyChanged(
            new PropertyChangedEventArgs(/* current value */ oldValue, /* new value */value));
    }
} = default(T);
Enter fullscreen mode Exit fullscreen mode

在我看来,这是 C# 10 中最有前景的功能之一,也是所有开发者最期待的功能之一。目前尚不清楚它何时正式发布,但我们会密切关注。


列表模式

让我们来看看微软对为何 C# 10 中尚未发布此功能的官方解释:

“我们已经完成了数组和可索引类型的语法设计和语义设计,但还需要对 IEnumerable 进行更多支持。我们希望在 C# 11 开发周期初期就能推出一个初步预览版,以便收集用户对我们目前设计方案的反馈。”

¯\ ( ͡° ͜ʖ ͡°)

“列表模式”是Alrz提出的一个功能,详情如下: 

“允许您将数组或列表与一系列模式进行匹配,例如,数组为 {1, 2, 3} 将匹配长度为 3 的整数数组,其元素分别为 1、2、3。”

为了更好地理解这一点,让我们来看他所举例子的一部分:

positional_pattern
  : type? positional_pattern_clause length_pattern_clause? property_or_list_pattern_clause? simple_designation?
  ;

property_or_list_pattern_clause
  : list_pattern_clause
  | property_pattern_clause
  ;

property_pattern_clause
  : '{' (subpattern (',' subpattern)* ','?)? '}'
  ;

list_pattern_clause
  : '{' pattern (',' pattern)* ','? '}'
  ;
Enter fullscreen mode Exit fullscreen mode

您可以在 GitHub 上的“列表模式”提案中查看完整的示例和更多信息


接口中的静态抽象

根据MadsTorgersen(本提案的贡献者)的说法,在接口中指定抽象静态成员会强制实现该接口的类和结构体在其接口实现中包含这些成员,无论是显式还是隐式。可以通过指定接口限制中未禁止的类型参数来访问这些成员。

当前技术的一个主要局限在于无法抽象静态成员并构建适用于指定这些静态成员的各种类型的通用代码。对于仅以静态形式存在的成员类型(例如运算符)而言,这个问题尤为棘手,因为它们的处理难度极大。

接口中的静态抽象允许实现基于数值类型的通用算法,这些算法由接口约束表示,这些约束指示了某些运算符的存在。因此,算法可以用以下运算符来描述:

// Interface specifies static properties and operators
interface IAddable<T> where T : IAddable<T>
{
    static abstract T Zero { get; }
    static abstract T operator +(T t1, T t2);
}

// Classes and structs (including built-ins) can implement interface
struct Int32 : , IAddable<Int32>
{
// Explicit
    static Int32 I.operator +(Int32 x, Int32 y) => x + y; 
// Implicit
    public static int Zero => 0;                          
}

// Generic algorithms can use static members on T
public static T AddAll<T>(T[] ts) where T : IAddable<T>
{
// Call static operator    
    T result = T.Zero;
// Use `+`                   
    foreach (T t in ts) { result += t; } 
    return result;
}

// Generic method can be applied to built-in and user-defined types
int sixtyThree = AddAll(new [] { 1, 2, 4, 8, 16, 32 });
Enter fullscreen mode Exit fullscreen mode

您可以在 GitHub 上的“接口中的静态抽象”提案中查看完整的示例和更多信息

MadsTorgesen还提出了一些替代方案,例如结构约束:

另一种方法是使用“结构约束”,直接且明确地要求类型参数上必须存在特定的运算符。这种方法的缺点是:

  • 每次都必须写出来。使用命名约束似乎更好。

  • 这是一种全新的约束类型,而所提出的功能则利用了现有的接口约束概念。
    它仅适用于运算符,而无法(轻易地)应用于其他类型的静态成员。


根据声明或模式

这是Alrz再次提出的一个功能,详情如下:

“允许在不同的互斥模式中声明模式变量。这是模式匹配提案中未被纳入 C# 9.0 的部分。”

如果每个互斥模式都创建一组不同类型的变量,那么这些变量在该特定代码路径中就不会被固定赋值,这正是我们所期望的。这包含了“或”模式,以及每次出现的 switch 语句等等。

模式变量可以在when子句中明确赋值,但不能在 switch 语句的主体中明确赋值,例如,由于以下原因:

case (int x, 0) a when Use(x, a): // ok
  case (0, int x) b when Use(x, b): // ok
     Use(x); // ok
     Use(a); // error; not definitely assigned
     Use(b); // error; not definitely assigned
     break;
Enter fullscreen mode Exit fullscreen mode

可以通过递归的方式,将等式两边的模式变量相乘,定义如下:

if (e is { A: (int x, 0) or (0, int x) } or
         { B: (int x, 0) or (0, int x) })
{
    Use(x);
}
Enter fullscreen mode Exit fullscreen mode

再次强调,如果您想彻底了解,我建议您深入阅读GitHub 上的“声明或模式提案” 。


C# 11 何时发布?

圣诞节发布 C# 11?我觉得这简直是梦想成真(微软低调行事也不是第一次了),不过考虑到 C# 10 已经发布了那么多新功能,可能性似乎不大。总之,未来几天我们就能知道了。

亲爱的读者朋友们,你们觉得C# 11会如何发展呢?请告诉我你们的看法!我也很想知道你们的意见 :)

如果您喜欢这篇文章,请不要忘记关注我们,这样您就可以第一时间了解 .NET 的最新动态。

文章来源:https://dev.to/bytehide/leaked-c-11-features-the-best-christmas-gift-from-microsoft-pn1