本文翻译于David Pine的这篇文章:Refactor your code with default lambda parameters 。
本文是探讨 C# 12的各种功能的四篇系列文章中的最后一篇。在这篇文章中,我们将探讨“默认 lambda 参数”功能,使开发人员能够在 lambda 表达式中使用默认参数值。本系列涵盖了很多内容:
- 使用默认 lambda 参数重构C#代码(本篇文章)
这些功能是我们不断努力提高代码可读性和可维护性的一部分。让我们详细探索它们!
默认 Lambda 参数🧮
默认 lambda 参数是 C# 12 中的一项新功能,允许开发人员在 lambda 中表达默认参数值。此功能是 C# 方法中现有默认参数功能的自然扩展。
C# 12 之前🕰️
在 C# 12 之前,当您定义需要提供某种默认行为的 lambda 表达式时,您必须使用空合并运算符 (??) 或条件运算符 (?:)。请查看以下示例:
var IncrementBy = static (int source, int? increment) =>
{
// Same as source + (increment.HasValue ? increment.Value : 1)
return source + (increment ?? 1);
};
Console.WriteLine(IncrementBy(5, null)); // 6
Console.WriteLine(IncrementBy(5, 2)); // 7
使用 C# 12 🤓
相反,使用默认 lambda 参数后,您可以直接在 lambda 表达式中定义 lambda 参数的默认值。默认 lambda 参数的语法类似于方法中默认参数的语法。默认值在参数名称和等号 (=) 后指定。请查看以下示例:
var IncrementBy = static (int source, int increment = 1) =>
{
return source + increment;
};
Console.WriteLine(IncrementBy(10)); // 11
Console.WriteLine(IncrementBy(10, 20)); // 30
当涉及默认参数时,Lambda 表达式遵循与方法相同的规则。默认值必须是编译时常量,并且必须与参数具有相同的类型。默认值在编译时进行计算,并且在调用 lambda 表达式时参数是可选的。
delegate int (int arg1, int arg2 = 1);
这意味着,从技术上讲,您可以使用参数的名称调用Lambda表达式,但它必须是匿名函数生成的名称。例如,以下扩展示例:
var IncrementByWithOffset = static (int source, int increment = 1, int offset = 100) =>
{
return source + increment + offset;
};
Console.WriteLine(IncrementByWithOffset(10)); // 111
Console.WriteLine(IncrementByWithOffset(10, 20)); // 130
Console.WriteLine(IncrementByWithOffset(10, 20, 0)); // 30
Console.WriteLine(IncrementByWithOffset(10, arg2: -100)); // 10
Console.WriteLine(IncrementByWithOffset(10, arg3: 0)); // 11
ASP.NET Core Minimal API 示例
让我们研究一个示例,其中我们有一个使用默认 lambda 参数的 ASP.NET Core Minimal API。来到 Visual Studio 2022 中的文件 > 新建 > 项目的对话框,创建一个新的 ASP.NET Core Web API 项目。或者,您可以使用以下 .NET CLI 命令来创建新项目:
dotnet new webapi -n WebApi
此模板创建一个具有单个 /weatherforecast 端点的新 ASP.NET Core Web API 项目。 /weatherforecast 端点返回五个随机天气预报的数组,请查看以下 Program.cs 文件中的模板代码:
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
var summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
app.MapGet("/weatherforecast", () =>
{
var forecast = Enumerable.Range(1, 5).Select(index =>
new WeatherForecast
(
DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
Random.Shared.Next(-20, 55),
summaries[Random.Shared.Next(summaries.Length)]
))
.ToArray();
return forecast;
})
.WithName("GetWeatherForecast")
.WithOpenApi();
app.Run();
internal record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary)
{
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}
这里有一段来自模板的代码,但它并不是我们真正要关注的重点。我们只需关注 MapGet 方法,因为它将我们的 lambda 功能映射到 HTTP GET 调用。
app.MapGet("/weatherforecast", () =>
{
var forecast = Enumerable.Range(1, 5).Select(index =>
new WeatherForecast
(
DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
Random.Shared.Next(-20, 55),
summaries[Random.Shared.Next(summaries.Length)]
))
.ToArray();
return forecast;
})
.WithName("GetWeatherForecast")
.WithOpenApi();
/weatherforecast 端点返回一个包含五个天气预报的数组。Enumerable.Range(1, 5) 方法调用中的硬编码 5 可以被默认 lambda 参数替换,以下是更新后的代码片段:
app.MapGet("/weatherforecast", (int days = 5) =>
{
// Safety check to ensure the days parameter is
// at least 1, but no more than 50.
var count = days is > 0 and <= 50
? days
: 5;
var forecast = Enumerable.Range(1, count).Select(index =>
new WeatherForecast
(
DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
Random.Shared.Next(-20, 55),
summaries[Random.Shared.Next(summaries.Length)]
))
.ToArray();
return forecast;
})
使用修改后的代码后,MapGet 方法现在接受一个默认值为 5 的可选 days 参数。因此,虽然仍然存在相同的默认行为,但我们向消费者公开了此参数。days 参数可以作为查询字符串传递给 API。例如,以下HTTP请求,该请求请求21天的天气预报:
GET /weatherforecast?days=21 HTTP/1.1
Host: localhost:7240
Scheme: https
当查询字符串中未提供 days 参数时,将使用此默认值。 days 参数用于指定应生成天气预报的天数。 有关 ASP.NET Core Minimal API 的详细信息,请参阅可选参数。
下一步计划
这就是关于 C# 12 部分新特性系列文章的全部内容了!!我希望您喜欢了解这些新功能以及它们如何帮助您重构代码。
在本文中,您了解了 C# 12 中的默认 lambda 参数功能。此功能允许开发人员在 lambda 中表达默认参数值。请务必在您自己的代码中尝试一下!如需更多资源,我建议您查看以下链接:
如果您有任何技术问题,欢迎来Microsoft Q&A 提问。
0 comments
Be the first to start the discussion.