.NET 6 Preview 7 发布

 .NET 6 Preview 7 现已。这是发布 RC 版本之前的最后一次预览。本次更新包括对各种功能的最后一点润色,以及一次性的大型功能发布,并且受 Visual Studio 2022 Preview 3 支持。

.NET SDK:现代化的 C# 项目模板

该版本更新了 .NET SDK 模板以使用最新的 C# 语言功能和模式。新模板中使用了以下语言功能:

  • Top-level 语句
  • 异步 Main
  • 全局 using 指令(通过 SDK 驱动的默认值)
  • 文件范围的命名空间
  • 目标类型的新表达式
  • 可空引用类型

通过项目模板启用这些功能,新代码可以从启用这些功能开始,但升级时现有代码不受影响。

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}

app.MapGet("/", () => "Hello World!");

app.Run();

可用于无效信息的反射 API

可空引用类型是编写可靠代码的重要特性,它非常适合编写代码,但不适用于检查。新的反射 API 使用户能够确定给定方法的参数和返回值的可空性性质。 对于上下文,该版本在 .NET 5 中向 .NET 库添加了可空性的注释(并在 .NET 6 中完成),并且正在对 ASP.NET Core 做同样的事情。可空性信息使用自定义属性保存在元数据中,原则上,任何人都可以读取自定义属性。

class Data
{
    public string?[] ArrayField;
    public (string?, object) TupleField;
}
private void Print()
{
    Type type = typeof(Data);
    FieldInfo arrayField = type.GetField("ArrayField");
    FieldInfo tupleField = type.GetField("TupleField");

    NullabilityInfoContext context = new ();

    NullabilityInfo arrayInfo = context.Create(arrayField);
    Console.WriteLine(arrayInfo.ReadState);        // NotNull
    Console.WriteLine(arrayInfo.Element.State);    // Nullable

    NullabilityInfo tupleInfo = context.Create(tupleField);
    Console.WriteLine(tupleInfo.ReadState);                      // NotNull
    Console.WriteLine(tupleInfo.GenericTypeArguments [0].State); // Nullable
    Console.WriteLine(tupleInfo.GenericTypeArguments [1].State); // NotNull
}

ZipFile 获得 Unix 文件权限

System.IO.Compression.ZipFile 类现在在创建和设置文件权限期间捕获 Unix 文件权限。此更改允许通过 zip 存档来回传送可执行文件,这意味着用户不再需要在解压缩 zip 存档后修改文件权限以使文件可执行。如果 zip 存档不包含文件权限,则提取的文件将获得默认文件权限,就像任何其他文件一样新创建的文件。

.NET 7 早期功能预览:通用数学

该版本在 .NET 6 中预览的其中一项功能是静态抽象接口成员,这允许用户在接口中定义静态抽象方法(包括运算符)。例如,现在可以实现代数泛型方法。对于某些用户来说,此功能可能是今年最出色的改进,它可能是自 Span<T> 以来最重要的新型系统功能。以下示例采用 IEnumerable<T>,并且由于 T 被约束为 INumber<T>,因此能够对所有值求和。

public static T Sum<T>(IEnumerable<T> values)
    where T : INumber<T>
{
    T result = T.Zero;

    foreach (var value in values)
    {
        result += value;
    }

    return result;
}

NativeMemory API

该版本添加了通过 System.Runtime.InteropServices.NativeMemory 公开的新本地内存分配 API,这些 API 与 malloc、free、realloc 和 calloc C API 等效,还包括用于进行对齐分配的 API。

System.Text.Json 序列化通知

System.Text.Json 序列化程序现在将通知作为(反)序列化操作的一部分公开,这对于默认值和验证很有用。要使用该功能,需要在 System.Text.Json.Serialization 命名空间内实现一个或多个接口 IJsonOnDeserialized、IJsonOnDeserializing、IJsonOnSerialized 或 IJsonOnSerializing。下面是一个在 JsonSerializer.Serialize() 和 JsonSerializer.Deserialize() 期间验证的示例,以确保 FirstName 属性不为空。

  public class Person : IJsonOnDeserialized, IJsonOnSerializing
  {
      public string FirstName{ get; set; }

      void IJsonOnDeserialized.OnDeserialized() => Validate(); // Call after deserialization
      void IJsonOnSerializing.OnSerializing() => Validate(); // Call before serialization

      private void Validate()
      {
          if (FirstName is null)
          {
              throw new InvalidOperationException("The 'FirstName' property cannot be 'null'.");
          }
      }
  }

W^X(write xor execute)支持所有平台和架构

运行时现在有一种模式,它不会同时创建或使用任何可写和可执行的内存页面,所有可执行内存都映射为只读。此功能已在 macOS(适用于 Apple Silicon)上和其它平台启用。此前在 Apple Silicon 机器上,同时可写和可执行的内存映射是被禁止的。

在这些平台上,可执行代码的生成/修改是通过单独的读写内存映射完成的,而这些映射是在与可执行代码地址不同的虚拟内存地址处创建的,并且仅在执行写入时存在很短的时间。例如,JIT 现在将代码生成到暂存缓冲区中,在整个方法被 jitt 之后,使用单个内存复制函数调用将代码复制到可执行内存中。并且可写映射生命周期仅跨越内存复制的时间。

用户可以通过将环境变量 DOTNET_EnableWriteXorExecute 设置为 1 来启用此新功能。此功能目前是可选的,因为它具有启动回归(Apple Silicon 除外)。预计在 .NET 7 中解决性能回归问题,并在那时默认启用该功能。

更多详细内容,请查看更新公告

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/95442.html

(0)
上一篇 2021年8月18日 09:26
下一篇 2021年8月18日 09:26

相关推荐

发表回复

登录后才能评论