C#11 更新预览 新特性一睹为快

1136

C# 11 更新带来了一些很棒的功能和更新,让我们一起来先睹为快。

如何体验

可以通过为其他编辑器下载Visual Studio 17.2 Preview 3.NET 7 Preview 3来检查更新并进行体验。

重点更新,一睹为快

  • 原始字符串 通过避免在字符串中转义内容来提高您的工作效率并提高可读性

    原始字符串文本可以包含任意文本,包括空格、引号和其他特殊字符甚至嵌入其他语言字符串(如 JSON、XML、HTML、SQL、Regex )等,而无需转义序列。

    举个例子,在之前的版本中,一个普通的字串符"\t",会被转义成制表符输出。而在这个版本的Raw string literals中,"\t" 就是 "\"和"t"两个字符。

    C#中原始字符串以至少三个双引号 ( """...""") 开头和结尾,其中任何数量小于原始字符串开始数量的双引号中的内容都被视为普通的字符,简单来说就是中间少于3个双引号的内容都是普通字符

    如果内容中有三个或者更多双引号,那么原始字符串比从内容以更多一个的引号开始即可。

    另外,原始字符串文字可以通过在它们前面加上$进行插值,字符串前缀$的数量就是指示嵌套代码表达式所需的花括号的数量。

    如下图,原始字符串文字以 $$ 为前缀,则单个大括号被视为内容,两个大括号才是指示嵌套代码。

    image.png

    除此之外,原始字符串还可以根据前导空格自动确定内容的缩进。

  • UTF-8 字符串 创建UTF-8字符串变得更容易、更不容易出错,从而提高生产力、弹性和性能

    C# 11之前,程序员必须要么将 UTF-8 转换为十六进制(这会导致冗长、不可读、容易出错的代码),要么在运行时对字符串文字进行编码。

    C# 11允许将仅包含 UTF-8 字符的字符串文字转换为其字节表示形式。这是在编译时完成的,因此字节可以随时使用而无需额外的运行时成本。所以你可以这么编码

    byte[] array = "hello";             // new byte[] { 0x68, 0x65, 0x6c, 0x6c, 0x6f }
    Span<byte> span = "dog";            // new byte[] { 0x64, 0x6f, 0x67 }
    ReadOnlySpan<byte> span = "cat";    // new byte[] { 0x63, 0x61, 0x74 }
    

    该特性正在进一步讨论中

  • 用户自定义运算符检查 允许用户自定义的运算符遵守当前的算术溢出检查状态,以获得更好的弹性体验

    用户可以通过<CheckForOverflowUnderflow>项目属性或checked/unchecked标识进行运算符溢出状态检查控制。

    目前支持检查版本的运算符是 ++-- 和 - 一元运算符以及 +-*, 和 / 二元运算符。没有修饰符的运算符在与选中的运算符配对时,将被取消选中,编译器将根据调用代码的上下文选择要使用的运算符。某些类型(例如浮点数)不会溢出,因此不需要单独的已检查和未检查运算符。

  • 自动默认结构 初始化结构值以提高生产力

    C# 10及更早版本中,您需要通过初始化字段和自动属性或在构造函数中设置它们来初始化结构的所有字段。如果您没有设置这些值,则会收到编译器错误。 从这个预览版开始,编译器将初始化任何未根据明确分配规则设置的字段和自动属性,并为其分配默认值。

  • Spans 模式匹配

    可以将 Span<char>ReadonlySpan<char> 与字符串文字进行模式匹配,比如下面这段代码

        static bool IsABC(Span<char> s) { 
            return s switch { 
                "ABC" => true,
                _ => false }; 
       }
    

    输入类型必须是已知静态的Span<char>ReadonlySpan<char>。另外,如果将Span<char>ReadonlySpan<char>与空常量匹配,编译器将报错。

  • 使用缓存委托进行方法组转换 以获得更好的性能

    通过缓存静态方法组而不是创建新的委托实例来提高运行时性能。从而提高应用程序的性能,尤其是对ASP.NET

  • 从 C# 11 中删除了参数空值检查

    在之前的版本中,允许在参数名称添加!! 从而在方法开始执行时进行空值检查。但是改功能反馈不佳。

    团队表示:

    我们没有足够的信心认为这是C#的正确功能设计,并且正在从C# 11中删除它。我们可能会在以后再次回到这个领域。

    目前,存在几种有效的方法对单行进行空值检测,例如,如果你使用.NET 6,建议你使用ArgumentNullException.ThrowIfNull方法

        public static void M(string myString)
        {
            ArgumentNullException.ThrowIfNull(myString);
            // method 
        }
    
  • 为小写类型名称添加了警告

    C# 11引入Warning Wave 7,对使用所有小写ASCII字符声明任何类型都会收获警告。因为C#偶尔会引入新的关键字,这些关键字都是小写的,可能与用户定义的小写类型名称冲突,如果它是小写的话。我们引入了此警告,以便您可以避免未来可能发生的重大更改。如果你遇到这种警告,可以检查并更新小写的类型名称,或者在它的用法前加上@,例如@lower

更加详细信息,请参考:devblogs.microsoft.com/dotnet/csha…