C#8.0特性(二)

接上回c# 8.0特性介绍, 这回我们开始介绍最新的C# 新特性,需要了解7.0特性以及上一篇文章的请点击下面的链接

当然放上目录:

  • Readonly 成员
  • 默认接口方法
  • 模式匹配增强功能
  • Using申明
  • 静态本地函数
  • 可处置的ref结构
  • 可为空的引用类型
  • 异步流
  • 索引和范围
  • Null合并赋值
  • 非托管构造类型
  • 嵌套表达式中的Stackalloc
  • 内插逐字字符串的增强功能
  • 平台支持情况

静态本地函数

在上次介绍c# 7.0增强特性中提到可以添加本地函数来增强代码的模块化以及可读性,这次再来看看在c# 8.0中上次提到的本地函数可以进一步被申明为静态的,即在本地函数前面加上 static 关键字,由于加上static后,本地函数变成静态的,所以可以确保本地函数不引用或使用封闭范围内的任何变量。示例:

<code>int Demo()
{
int y = 5;
int x = 7;
return Add(x, y);

static int Add(Int32 left, Int32 right) => left + right;
}/<code>

Disposable ref structs

ref struct 这样声明的结构无法实现额外的接口,因此无法实现IDisposable这个接口,但是可以通过提供一个可以访问的void Dispose()方法,来实现Dispose的功能; readonly ref struct 这样的结构也是可以的

可为空引用类型

在可为空注释上下文中,引用类型的任何变量都被视为不可为空引用类型 。 若要指示一个变量可能为 null,必须在类型名称后面附加 ?,以将该变量声明为可为空引用类型 。

任何引用类型都可以具有四个“为 Null 性”中的一个,它描述了何时生成警告 :

  • 不可为空:无法将 null 分配给此类型的变量。 在取消引用之前,无需对此类型的变量进行 null 检查。
  • 可为空:可将 null 分配给此类型的变量。 在不首先检查 null 的情况下取消引用此类型的变量时发出警告。
  • 无视:这是 C# 8.0 之前版本的状态。 可以取消引用或分配此类型的变量而不发出警告。
  • 未知:这通常针对类型参数,约束不告知编译器类型是否必须是“可为空”或“不可为空” 。

在C#8.0 以前的版本。默认被认为是不启用的,在之后的版本中用 .csproj 文件中的 Nullable 元素为项目设置可为空注释上下文和可为空警告上下文

<code>// .csproj 文件中的配置是全局的
<nullable>enable/<nullable>
<nullable>warnings/<nullable>
<nullable>annotations/<nullable>
<nullable>disable/<nullable>
// 使用指令来局部指定 示例如下
#nullable enable 将可为空注释上下文和可为空警告上下文设置为“已启用” 。
#nullable disable warnings 将可为空警告上下文设置为“已禁用” 。/<code>

异步流

从 C# 8.0 开始,可以创建并以异步方式使用流。 返回异步流的方法有三个属性:

  1. 它是用 async 修饰符声明的。
  2. 它将返回 IAsyncEnumerable
  3. 该方法包含用于在异步流中返回连续元素的 yield return 语句。

使用异步流需要在枚举流元素时在 foreach 关键字前面添加 await 关键字。

<code>await foreach (var number in GenerateSequence())
{
Console.WriteLine(number);
}/<code>

索引和范围

索引和范围为访问序列中的单个元素或范围提供了简洁的语法。此特性依赖于两个新类型以及两个新运算符

  • System.Index 表示一个序列索引。
  • 来自末尾运算符 ^ 的索引,指定一个索引与序列末尾相关。
  • System.Range 表示序列的子范围。
  • 范围运算符 ..,用于指定范围的开始和末尾,就像操作数一样。
  • <code>// A string array contains some string 
    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
    Console.WriteLine($"The last word is {words[^1]}"); // writes "dog"
    var quickBrownFox = words[1..4]; // 包含 quick brown fox 不包含 jumped
    var lazyDog = words[^2..^0]; // 包含 lazy dog
    var allWords = words[..]; // 包含 "The" 到 "dog"的所有元素
    var firstPhrase = words[..4]; // 包含 "The" 到 "fox"
    var lastPhrase = words[6..]; // 包含 "the", "lazy", "dog"
    Range phrase = 1..4; // 通过此来声明一个范围
    var text = words[phrase]; // 在中括号中使用刚刚声明的phrase/<code>

    Null 合并赋值

    新的运算符被 ??= 定义,仅当左操作数计算为 null 时,才能使用运算符 ??= 将其右操作数的值分配给左操作数。

    <code>List numbers = null;
    int? i = null;

    numbers ??= new List();
    numbers.Add(i ??= 17);
    /<code>

    非托管构造类型

    在 C# 7.3 及更低版本中,构造类型(包含至少一个类型参数的类型)不能为非托管类型。 从 C# 8.0 开始,如果构造的值类型仅包含非托管类型的字段,则该类型不受管理。

    <code>public struct Coords
    {

    public T X;
    public T Y;
    }
    // Coords 类型为 C# 8.0 及更高版本中
    // 的非托管类型。 与任何非托管类型一样,可
    // 以创建指向此类型的变量的指针,或针对此类
    // 型的实例在堆栈上分配内存块:
    Span<coords>> coordinates = stackalloc[]
    {
    new Coords { X = 0, Y = 0 },
    new Coords { X = 0, Y = 3 },
    new Coords { X = 4, Y = 0 }
    };
    /<coords>
    /<code>

    嵌套表达式中的 stackalloc

    如果 stackalloc 表达式的结果为 System.Span 或 System.ReadOnlySpan 类型,则可以在其他表达式中使用 stackalloc 表达式

    <code>Span numbers = stackalloc[] { 1, 2, 3, 4, 5, 6 };
    var ind = numbers.IndexOfAny(stackalloc[] { 2, 4, 6 ,8 });
    Console.WriteLine(ind); // output: 1
    /<code>

    内插逐字字符串的增强功能

    内插逐字字符串中 $ 和 @ 标记的顺序可以任意安排:$@"..." 和 @$"..." 均为有效的内插逐字字符串。 在早期 C# 版本中,$ 标记必须出现在 @ 标记之前。

    <code>// in previous versions of c# 
    var filePath = $@"c:\\demoDir\\{testDir}\\demo.txt";
    // in c# 8.0 but also type as bellow
    var filePath = @$"c:\\demoDir\\{testDir}\\demo.txt";/<code>

    好了,本次的主要内容就到这里了后面的内容是关于各个.Net平台的支持情况

    目标框架 version C# 语言版本的默认值

    .NET Core 3.x C# 8.0

    .NET Core 2.x C# 7.3

    .NET Standard 2.1 C# 8.0

    .NET Standard 2.0 C# 7.3

    .NET Standard 1.x C# 7.3

    .NET Framework all C# 7.3


    分享到:


    相關文章: