.NET 8.0中有哪些新的变化?
作者:葡萄城技术团队
链接:https://my.oschina.net/powertoolsteam/blog/10143465
.NET 8已正式GA
客户聊天机器人
检索增强生成
使用 Azure AI 服务开发应用程序
.NET MAUI 提供单一项目系统和单一代码库来构建 WinUI、Mac Catalyst、iOS 和 Android 应用程序。本机 AOT(实验性)现在支持针对类似 iOS 的平台。适用于 .NET MAUI 的新 Visual Studio Code 扩展为您提供了开发跨平台 .NET 移动和桌面应用程序所需的工具。现在支持 Xcode 15 和 Android API 34,允许您瞄准最新版本的 iOS 和 Android。在性能、控件和 UI 元素以及特定于平台的行为方面进行了大量的质量改进,例如桌面交互添加了更好的点击处理、键盘侦听器等。
int[] x1 = new int[] { 1, 2, 3, 4 };
int[] x2 = Array.Empty<int>();
WriteByteArray(new[] { (byte)1, (byte)2, (byte)3 });
List<int> x4 = new() { 1, 2, 3, 4 };
Span<DateTime> dates = stackalloc DateTime[] { GetDate(0), GetDate(1) };
WriteByteSpan(stackalloc[] { (byte)1, (byte)2, (byte)3 });
public class BankAccount(string accountID, string owner)
{
public string AccountID { get; } = accountID;
public string Owner { get; } = owner;
public override string ToString() => $"Account ID: {AccountID}, Owner: {Owner}";
}
作为 base () 构造函数调用的参数。
初始化成员字段或属性。
在实例成员中引用构造函数参数。
删除依赖注入中的样板。
using intArray = int[]; // Array types.
using Point = (int x, int y); // Tuple type
using unsafe ArrayPtr = int*; // Pointer type (requires "unsafe")
var IncrementBy = (int source, int increment = 1) => source + increment;
Console.WriteLine(IncrementBy(5)); // 6
Console.WriteLine(IncrementBy(5, 2)); // 7
[System.Runtime.CompilerServices.InlineArray(10)]
public struct Buffer
{
private int _element0;
}
它们的用法与任何其他数组类似:
var buffer = new Buffer();
for (int i = 0; i < 10; i++)
{
buffer[i] = i;
}
foreach (var i in buffer)
{
Console.WriteLine(i);
}
// Sample class that contains a function pointer field.
public unsafe class UClass
{
public delegate* unmanaged[Cdecl, SuppressGCTransition]<in int, void> _fp;
}
// ...
FieldInfo fieldInfo = typeof(UClass).GetField(nameof(UClass._fp));
// Obtain the function pointer type from a field.
Type fpType = fieldInfo.FieldType;
// New methods to determine if a type is a function pointer.
Console.WriteLine($"IsFunctionPointer: {fpType.IsFunctionPointer}");
Console.WriteLine($"IsUnmanagedFunctionPointer: {fpType.IsUnmanagedFunctionPointer}");
// New methods to obtain the return and parameter types.
Console.WriteLine($"Return type: {fpType.GetFunctionPointerReturnType()}");
foreach (Type parameterType in fpType.GetFunctionPointerParameterTypes())
{
Console.WriteLine($"Parameter type: {parameterType}");
}
// Access to custom modifiers and calling conventions requires a "modified type".
Type modifiedType = fieldInfo.GetModifiedFieldType();
// A modified type forwards most members to its underlying type.
Type normalType = modifiedType.UnderlyingSystemType;
// New method to obtain the calling conventions.
foreach (Type callConv in modifiedType.GetFunctionPointerCallingConventions())
{
Console.WriteLine($"Calling convention: {callConv}");
}
// New method to obtain the custom modifiers.
foreach (Type modreq in modifiedType.GetFunctionPointerParameterTypes()[0].GetRequiredCustomModifiers())
{
Console.WriteLine($"Required modifier for first parameter: {modreq}");
}
输出:
IsFunctionPointer: True
IsUnmanagedFunctionPointer: True
Return type: System.Void
Parameter type: System.Int32&
Calling convention: System.Runtime.CompilerServices.CallConvSuppressGCTransition
Calling convention: System.Runtime.CompilerServices.CallConvCdecl
Required modifier for first parameter: System.Runtime.InteropServices.InAttribute
<PropertyGroup>
<EnableConfigurationBindingGenerator>true</EnableConfigurationBindingGenerator>
</PropertyGroup>
以下代码演示了调用绑定器的示例:
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
IConfigurationSection section = builder.Configuration.GetSection("MyOptions");
// !! Configure call - to be replaced with source-gen'd implementation
builder.Services.Configure<MyOptions>(section);
// !! Get call - to be replaced with source-gen'd implementation
MyOptions options0 = section.Get<MyOptions>();
// !! Bind call - to be replaced with source-gen'd implementation
MyOptions options1 = new MyOptions();
section.Bind(options1);
WebApplication app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.Run();
public class MyOptions
{
public int A { get; set; }
public string S { get; set; }
public byte[] Data { get; set; }
public Dictionary<string, string> Values { get; set; }
public List<MyClass> Values2 { get; set; }
}
public class MyClass
{
public int SomethingElse { get; set; }
}
<PropertyGroup>
<AndroidStripILAfterAOT>true</AndroidStripILAfterAOT>
</PropertyGroup>
默认情况下,将 AndroidStripILAfterAOT 设置为 true 会替代默认的 AndroidEnableProfiledAot 设置,从而允许剪裁已 AOT 编译的(几乎)所有方法。 还可通过将两个属性都显式设置为 true 来结合使用分析的 AOT 和 IL 条带化:
<PropertyGroup>
<AndroidStripILAfterAOT>true</AndroidStripILAfterAOT>
<AndroidEnableProfiledAot>true</AndroidEnableProfiledAot>
</PropertyGroup>
规则 ID | 类别 | 说明 |
---|---|---|
CA1856 | 性能 | 未在参数上正确应用 ConstantExpectedAttribute 属性时触发。 |
CA1857 | 性能 | 当参数使用 ConstantExpectedAttribute 添加批注但提供的参数不是常量时触发。 |
CA1858 | 性能 | 若要确定字符串是否以给定前缀开头,最好调用 String.StartsWith,而不是调用 String.IndexOf,然后将结果与零进行比较。 |
CA1859 | 性能 | 此规则建议尽可能将特定局部变量、字段、属性、方法参数和方法返回类型从接口或抽象类型升级到具体类型。 使用具体类型可生成更高质量的代码。 |
CA1860 | 性能 | 若要确定集合类型是否具有任何元素,最好使用 Length、Count 或 IsEmpty,而不是调用 Enumerable.Any。 |
CA1861 | 性能 | 重复调用时,不会重复使用作为参数传递的常量数组,这意味着每次都会创建一个新数组。 若要提高性能,请考虑将数组提取到静态只读字段。 |
CA1865-CA1867 | 性能 | 对于单字符串,char 重载的性能更好。 |
CA2021 | 可靠性 | Enumerable.Cast(IEnumerable) 和 Enumerable.OfType(IEnumerable) 需要兼容的类型才能正常运行。 泛型类型不支持扩大转换和用户定义的转换。 |
CA1510-CA1513 | 可维护性 | 在构造新的异常实例方面,引发帮助程序比 if 块更简单、更高效。 这四个分析器是为以下例外情况创建的:ArgumentNullException、ArgumentException、ArgumentOutOfRangeException 和 ObjectDisposedException。 |
检索本地和 UTC 时间
获取用于测量性能的时间戳
创建计时器
// Get system time.
DateTimeOffset utcNow = TimeProvider.System.GetUtcNow();
DateTimeOffset localNow = TimeProvider.System.GetLocalNow();
// Create a time provider that works with a
// time zone that's different than the local time zone.
private class ZonedTimeProvider : TimeProvider
{
private TimeZoneInfo _zoneInfo;
public ZonedTimeProvider(TimeZoneInfo zoneInfo) : base()
{
_zoneInfo = zoneInfo ?? TimeZoneInfo.Local;
}
public override TimeZoneInfo LocalTimeZone => _zoneInfo;
public static TimeProvider FromLocalTimeZone(TimeZoneInfo zoneInfo) =>
new ZonedTimeProvider(zoneInfo);
}
// Create a timer using a time provider.
ITimer timer = timeProvider.CreateTimer(callBack, state, delay, Timeout.InfiniteTimeSpan);
// Measure a period using the system time provider.
long providerTimestamp1 = TimeProvider.System.GetTimestamp();
long providerTimestamp2 = TimeProvider.System.GetTimestamp();
var period = GetElapsedTime(providerTimestamp1, providerTimestamp2);
static bool FormatHexVersion(
short major,
short minor,
short build,
short revision,
Span<byte> utf8Bytes,
out int bytesWritten) =>
Utf8.TryWrite(
utf8Bytes,
CultureInfo.InvariantCulture,
$"{major:X4}.{minor:X4}.{build:X4}.{revision:X4}",
out bytesWritten);
// Hashing example
if (SHA3_256.IsSupported)
{
byte[] hash = SHA3_256.HashData(dataToHash);
}
else
{
// ...
}
// Signing example
if (SHA3_256.IsSupported)
{
using ECDsa ec = ECDsa.Create(ECCurve.NamedCurves.nistP256);
byte[] signature = ec.SignData(dataToBeSigned, HashAlgorithmName.SHA3_256);
}
else
{
// ...
}
namespace System.IO.Compression;
public static partial class ZipFile
{
public static void CreateFromDirectory(string sourceDirectoryName, Stream destination);
public static void CreateFromDirectory(string sourceDirectoryName, Stream destination, CompressionLevel compressionLevel, bool includeBaseDirectory);
public static void CreateFromDirectory(string sourceDirectoryName, Stream destination, CompressionLevel compressionLevel, bool includeBaseDirectory, Encoding? entryNameEncoding);
public static void ExtractToDirectory(Stream source, string destinationDirectoryName) { }
public static void ExtractToDirectory(Stream source, string destinationDirectoryName, bool overwriteFiles) { }
public static void ExtractToDirectory(Stream source, string destinationDirectoryName, Encoding? entryNameEncoding) { }
public static void ExtractToDirectory(Stream source, string destinationDirectoryName, Encoding? entryNameEncoding, bool overwriteFiles) { }
}
END
微信扫码关注该文公众号作者
戳这里提交新闻线索和高质量文章给我们。
来源: qq
点击查看作者最近其他文章