如何修改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
相关产品推荐
相关产品推荐

