IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    C#12新功能合集四:使用默认 lambda 参数重构C#代码

    Amy Peng发表于 2024-07-22 06:40:16
    love 0

    本文翻译于David Pine的这篇文章:Refactor your code with default lambda parameters 。

    本文是探讨 C# 12的各种功能的四篇系列文章中的最后一篇。在这篇文章中,我们将探讨“默认 lambda 参数”功能,使开发人员能够在 lambda 表达式中使用默认参数值。本系列涵盖了很多内容: 

    • 使用主构造函数重构 C# 代码 
    • 使用集合表达式重构 C# 代码 
    • 使用任意类型别名重构 C# 代码 
    • 使用默认 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 中表达默认参数值。请务必在您自己的代码中尝试一下!如需更多资源,我建议您查看以下链接: 

    • C# 语言参考:Lambda 表达式 
    • C# 语言参考:Lambda 方法组默认值 

    如果您有任何技术问题,欢迎来Microsoft Q&A 提问。

    The post C#12新功能合集四:使用默认 lambda 参数重构C#代码 appeared first on .NET中文官方博客.



沪ICP备19023445号-2号
友情链接