在这篇文章中,我将简要提及 .NET 8 的新功能和变化。
dotnet publish
和 dotnet pack
发布模式
使用此新版本,dotnet publish
和 dotnet pack
命令将以 Release
模式进行构建和打包。在此之前,它是在 Debug
模式下生成的。为了能够在 Debug
模式下生成,您需要将此参数 -p:PublishRelease
设置为 false
。
dotnet publish -> /app/bin/Release/net8.0/app.dll
dotnet publish -p:PublishRelease=false -> /app/bin/Debug/net8.0/app.dll
System.Text.Json
序列化
在最近的版本中,System.Text.Json
替换了 Newtonsoft.Json
。我们现在也在 ABP
框架中使用 System.Text.Json
。对象序列化和反序列化有多项增强功能。
最新版本的源代码生成器在与 ASP.NET Core
一起使用时,为 Native AOT
应用程序提供了改进的性能和可靠性。它还允许使用基于反射的序列化中已支持的 required
属性和 init
属性对类型进行序列化。此外,现在还有一个选项,可以自定义处理 JSON
有效负载中不存在的成员,请参阅 https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/missing-members。
支持对接口层次结构中的属性进行序列化。JsonNamingPolicy
功能已扩展到包括用于 snake_case
和 kebab-case
属性名称转换的新命名策略。最后,JsonSerializerOptions.MakeReadOnly
方法允许显示控制 JsonSerializerOptions
实例何时被冻结,您可以使用 IsReadOnly
属性检查其状态。
随机性
如今,人工智能编程非常流行。 并且产生了生产更多随机内容的需求。
GetItems()
引入了两种新方法:Random.GetItems
和 RandomNumberGenerator.GetItems
,使开发人员能够从给定的输入集中随机选择一定数量的项目。 下面的示例演示了如何使用 System.Random.GetItems<T>()
方法,该方法从 Random.Shared
属性随机获取 2 个项目随机插入到数组中。
private static ReadOnlySpan<CountryPhoneCodePhoneCode> countries = new[]
{
new CountryPhoneCode("Turkey", "90"),
new CountryPhoneCode("China", "86"),
new CountryPhoneCode("Germany", "49"),
new CountryPhoneCode("Finland", "358"),
new CountryPhoneCode("Spain", "34")
};
var randomValues = Random.Shared.GetItems(countries, 2);
foreach (var x in randomValues)
{
Console.WriteLine(x.Name + " -> " + x.CountryPhoneCode);
}
/**************
- Output -
Germany -> 49
Finland -> 358
**************/
Shuffle()
如果您需要在应用程序中随机化一个范围的顺序,您可以利用两种新方法:Random.Shuffle
和 RandomNumberGenerator.Shuffle
。当您希望通过改变训练和测试数据的呈现顺序来最大程度地减少机器学习中训练偏差的影响时,这些方法特别方便。 使用这些方法,您可以确保数据集中的第一项仅有时用于训练,最后一项仅有时保留用于测试。
var trainingData = GetData();
Random.Shared.Shuffle(trainingData);
IDataView source = mlContext.Data.LoadFromEnumerable(trainingData);
DataOperationsCatalog.TrainTestData splittedData = mlContext.Data.TrainTestSplit(source);
model = chain.Fit(splittedData.TrainSet);
IDataView resultPredictions = model.Transform(split.TestSet);
性能改进
- 在
.NET 8
中,引入了各种新类型来提升应用程序性能。.NET 8
中的System.Collections.Frozen
命名空间包括FrozenDictionary
和FrozenSet
集合类型。这些类型旨在防止在创建集合后对键和值进行更改,从而实现更快的读取操作,如TryGetValue()
。它们特别适用于在首次使用时填充的集合,然后持久化用于长期运行的服务。
private static readonly FrozenDictionary<string, bool> frozenData = LoadConfigurationData().ToFrozenDictionary(optimizeForReads: true);
//////
if (frozenData.TryGetValue(key, out bool setting) && setting)
{
Process();
}
Buffers.IndexOfAnyValues
是.NET 8
中的一种新类型,旨在传递给搜索传递集合中任何值的第一个出现的方法。像String.IndexOfAny
和MemoryExtensions.IndexOfAny
这样的方法的新重载接受新类型的实例。当您创建Buffers.IndexOfAnyValues
的实例时,所有优化后续搜索所需的数据都会在那个时候派生出来。Text.CompositeFormat
是.NET 8
中的一种新类型,用于优化在编译时未知的格式字符串(例如从资源文件加载的格式字符串)。虽然会在前期花费一些额外时间来执行诸如解析字符串之类的任务,但它可以避免每次使用格式字符串时都进行这些工作。
private static readonly CompositeFormat range = CompositeFormat.Parse(Load());
//////////
static string GetMessage(int min, int max) =>
string.Format(CultureInfo.InvariantCulture, range, min, max);
- 在
.NET 8
中,引入了两种新类型来实现快速的XxHash3
和XxHash128
哈希算法。
System.Numerics
和 System.Runtime.Intrinsics
的改进
对于 System.Numerics
和 System.Runtime.Intrinsics
命名空间进行了多项增强。这些改进包括在 .NET 8
中为 Vector256
、Matrix3x2
和 Matrix4x4
提供更好的硬件加速。
Vector256
经过重新设计,内部利用 2 个 Vector128<T>
操作,在 Arm64
处理器上部分加速某些函数,其中 Vector128.IsHardwareAccelerated == true
,但 Vector256.IsHardwareAccelerated == false
。.NET 8
还引入了 Vector512
。
此外,还向硬件内部引入了 ConstExpected
属性,以在非常量值可能导致意外性能问题时提醒用户。
最后, IFloatingPointIeee754
接口中添加了 Lerp(TSelf, TSelf, TSelf) API
,可以高效准确地对 float(Single)
、double(Double)
和 Half
类型的两个值进行线性插值。
新的数据验证属性
DataAnnotations
命名空间专门用于云原生服务中的验证。现有的 DataAnnotations
验证器主要用于验证用户数据,如表单字段。然而,新的属性旨在验证非用户输入的数据,如配置选项。除了新的属性之外,RangeAttribute
和 RequiredAttribute
类型也新增了一些属性。
RequiredAttribute.DisallowAllDefaultValues
:该属性强制要求结构体与其默认值不相等。RangeAttribute.MinimumIsExclusive
和RangeAttribute.MaximumIsExclusive
:指定可接受范围是否包括其边界。DataAnnotations.LengthAttribute
:使用Length
属性指定字符串或集合的下限和上限。例如,[Length(5, 100)]
属性指定集合必须至少有5
个元素,最多有100
个元素。DataAnnotations.Base64StringAttribute
:验证有效的Base64
格式。DataAnnotations.AllowedValuesAttribute
和DataAnnotations.DeniedValuesAttribute
:指定接受的允许列表或不允许的拒绝列表。例如:[AllowedValues("red", "green", "blue")]
或[DeniedValues("yellow", "purple")]
。
函数指针自省支持
在 .NET 5
中引入了函数指针。当时还不支持反射。因此,对函数指针使用 typeof
或反射(例如typeof(delegate<void>())
或 FieldInfo.FieldType
)将返回一个 IntPtr
。然而,在 .NET 8
中,将返回一个 System.Type
对象,可以访问函数指针的元数据,如调用约定、返回类型和参数。这个功能只在 CoreCLR
运行时和 MetadataLoadContext
中实现。
Native AOT
在 .NET 7
中首次引入了作为本机 AOT
的发布方式,将应用程序发布为本机 AOT
的选项可以创建一个自包含的应用程序版本,无需单独的运行时,将所有内容捆绑到一个单独的文件中。在 .NET 8
中,本机 AOT
的支持现在包括 macOS
上的 x64
和 Arm64
架构。此外,Linux
上的本机 AOT
应用程序现在的大小缩小了多达 50%。下表显示了使用本机 AOT
发布的最小应用程序的大小,其中包含了整个 .NET
运行时:
Linux x64 (with -p:StripSymbols=true)
- .NET 7 ➡ 3.76MB
- .NET 8 ➡ 1.84 MB
Windows x64
- .NET 7 ➡ 2.85 MB
- .NET 8 ➡ 1.77 MB
代码生成改进
.NET 8
增加了对代码生成和即时编译(JIT
)的改进:
- JIT 吞吐量的提升
- Arm64 性能的提升
- 支持基于程序分析的优化(PGO)的改进
- 支持 AVX-512 ISA 扩展
- SIMD (单指令多数据) 改进
- 云原生改进
- 循环和一般优化
.NET 8 DevOps 改进
容器镜像变化
在 .NET 8
中,容器镜像发生了一些变化。首先,容器镜像默认使用 Debian 12
作为 Linux
发行版。
其次,镜像中包含了一个非 root
用户,使得镜像具备非 root
用户的能力。要以非 root
用户身份运行,请在 Dockerfile
的末尾添加一行 USER app
。
此外,默认端口也已从 80
更改为 8080
,并且可使用新的环境变量 ASPNETCORE_HTTP_PORTS
轻松更改端口。
与 ASPNETCORE_URLS
所需的格式相比,ASPNETCORE_HTTP_PORTS
变量的格式更简单,并且接受一个端口列表。如果使用其中一种变量将端口更改回 80
,将无法以非 root
用户身份运行。
最后,Chiseled Ubuntu
镜像现已支持 .NET 8
,并可在 [Ubuntu/DotNet-deps Docker Hub]
(Ubuntu/DotNet-deps Docker Hub
)上获得。Chiseled
镜像经过精简,具有更小的攻击面,它们被精简为超紧凑,并且不包含软件包管理器或 Shell
。Chiseled
镜像是非 root
用户,非常适合寻求应用类计算好处的开发人员。这些镜像定期发布到 .NET
每夜版本的存储库中,以便轻松访问。
在 Linux 上构建你的 .NET
在早期版本中,从源代码构建 .NET
在先前版本中需要从对应的发布提交中创建源代码压缩包。然而,在 .NET 8
中,这一步骤不再必要,因为 dotnet/dotnet
存储库允许在 Linux
上直接使用 dotnet/source-build
构建 .NET
,以创建运行时、工具和 SDK
。Red Hat
和 Canonical
也使用此构建来构建 .NET
。对于大多数人来说,使用容器进行构建是最简单的方法,因为 dotnet-buildtools/prereqs
容器镜像具有所有必要的依赖关系。构建指南提供了更多信息。
Linux的最低支持基线
针对 .NET 8
,Linux
的支持要求已进行更新,最低支持基线发生了变化:
所有架构都将以 Ubuntu 16.04
为目标进行 .NET
的构建,这对于设置 .NET 8
所需的最低 glibc
版本非常重要。早于 16.04
的 Ubuntu
版本(如14.04
)将无法启动 .NET 8
。 不再使用 .NET 8
支持 Red Hat Enterprise Linux 7
,只支持 RHEL 8
及更高版本。
原文:https://community.abp.io/posts/whats-new-in-.net-8-discover-all-.net-8-features-llcmrdre
Comments