https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-12
记录类型作为类或结构的类型修饰符引入,这简化了构建简单类(如数据容器)的语法。记录可以包括主构造函数。该构造函数不仅生成一个支持字段,而且还为每个参数公开一个公共属性。与传统的类或结构类型不同,在传统的类或结构类型中,主构造函数参数可以在整个类定义中访问,而记录被设计为透明的数据容器。他们本质上支持基于值的相等,这与他们作为数据持有者的预期角色相一致。因此,它们的主构造函数参数可以作为属性访问是合乎逻辑的
.NET 提供了许多模板,如果您曾经创建过 Worker Service,您可能见过以下 Worker 类模板代码:
namespace Example.Worker.Service
{
public class Worker : BackgroundService
{
private readonly ILogger<Worker> _logger;
public Worker(ILogger<Worker> logger)
{
_logger = logger;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
if (_logger.IsEnabled(LogLevel.Information))
{
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
}
await Task.Delay(1000, stoppingToken);
}
}
}
}
值得一提的是,Visual Studio Code 中不提供此特定功能的重构工具,但您可以手动重构主构造函数。若要在 Visual Studio 中使用主构造函数重构此代码,可以使用“使用主构造函数(并删除字段)”重构选项。右键单击 Worker 构造函数,选择“快速操作和重构…”(或按 Ctrl + .),然后选择“使用主构造函数”(并删除字段)。
现在生成的代码类似于以下 C# 代码:
namespace Example.Worker.Service
{
public class Worker(ILogger<Worker> logger) : BackgroundService
{
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
if (logger.IsEnabled(LogLevel.Information))
{
logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
}
await Task.Delay(1000, stoppingToken);
}
}
}
}
https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/types/records
.NET 提供了许多模板
https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-new
Worker Service
https://learn.microsoft.com/en-us/dotnet/core/extensions/workers
namespace Example.Worker.Service;
public class Worker(ILogger<Worker> logger) : BackgroundService
{
private readonly ILogger<Worker> _logger = logger;
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
if (_logger.IsEnabled(LogLevel.Information))
{
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
}
await Task.Delay(1000, stoppingToken);
}
}
}
namespace Example.Worker.Service
{
// Primary constructor
public class Worker(ILogger<Worker> logger) : BackgroundService
{
private readonly int _delayDuration = 1_000;
// Secondary constructor, calling the primary constructor
public Worker(ILogger<Worker> logger, int delayDuration) : this(logger)
{
_delayDuration = delayDuration;
}
// Omitted for brevity...
}
}
并不总是需要额外的构造函数。让我们进行一些额外的重构以包含一些其他功能!
C# 包含文件范围的命名空间。它们是减少嵌套级别和提高可读性的重要功能。继续前面的示例,将光标放在命名空间名称的末尾,然后按 ; 键(Visual Studio Code 不支持此操作,但您可以手动执行此操作)。这会将命名空间转换为文件范围的命名空间。
经过一些额外的编辑,最终的重构代码如下:
namespace Example.Worker.Service;
public sealed class Worker(ILogger<Worker> logger) : BackgroundService
{
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
if (logger.IsEnabled(LogLevel.Information))
{
logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
}
await Task.Delay(1_000, stoppingToken);
}
}
}
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/integral-numeric-types#integer-literals
C# 中的新增功能
https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-13
原创文章,作者:guozi,如若转载,请注明出处:https://www.sudun.com/ask/89330.html