You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改Product类消除构造函数参数price1与price2的歧义?

解决Product类构造函数参数歧义的方案

原代码中,Product构造函数的两个double类型参数容易因位置传反而引发Bug,编译器无法自动验证参数正确性。以下是几种可行的修改方案:

方案一:用强类型包装业务值

为两个价格分别定义专属的结构体,让参数类型不同,从根源上杜绝传反问题:

// 为Price1定义专属值类型
public struct Price1
{
    public double Value { get; }
    public Price1(double value) => Value = value;
}

// 为Price2定义专属值类型
public struct Price2
{
    public double Value { get; }
    public Price2(double value) => Value = value;
}

public sealed class Product
{
    [JsonConstructor]
    public Product(Price1 price1, Price2 price2)
    {
        Price1 = price1.Value;
        Price2 = price2.Value;
    }

    [JsonProperty(PropertyName = "price1")]
    public double Price1 { get; }

    [JsonProperty(PropertyName = "price2")]
    public double Price2 { get; }
}

调用时必须传入对应类型的实例,比如new Product(new Price1(19.99), new Price2(29.99)),传反会直接触发编译器错误。若需兼容JSON序列化,可为结构体添加对应的JsonConverter。

方案二:使用静态工厂方法封装构造逻辑

将构造函数设为私有,通过命名清晰的静态工厂方法创建实例,强制调用者明确参数含义:

public sealed class Product
{
    // 私有构造函数,仅内部调用
    private Product(double price1, double price2)
    {
        Price1 = price1;
        Price2 = price2;
    }

    [JsonProperty(PropertyName = "price1")]
    public double Price1 { get; }

    [JsonProperty(PropertyName = "price2")]
    public double Price2 { get; }

    // 明确参数含义的工厂方法
    public static Product Create(double price1, double price2)
    {
        return new Product(price1, price2);
    }

    // 若价格有业务区分,可进一步细化方法名
    public static Product CreateWithWholesaleAndRetailPrices(double wholesalePrice, double retailPrice)
    {
        return new Product(wholesalePrice, retailPrice);
    }
}

调用时推荐使用具名参数,比如Product.Create(price1: 19.99, price2: 29.99),编译器会验证参数名的正确性,避免位置传反。

方案三:改用C# 9+的记录类型(属性初始化模式)

利用记录类型的init属性,创建实例时必须显式指定属性名,完全消除位置歧义:

public sealed record Product
{
    [JsonProperty(PropertyName = "price1")]
    public double Price1 { get; init; }

    [JsonProperty(PropertyName = "price2")]
    public double Price2 { get; init; }
}

创建实例时需写成new Product { Price1 = 19.99, Price2 = 29.99 },编译器会自动验证属性名,同时System.Text.Json原生支持init属性的序列化/反序列化,无需额外配置构造函数特性。

内容的提问来源于stack exchange,提问作者PurpleGreen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 11:23:12