C#中优雅处理字符串二选一合法值的优化方案问询
优化字符串类型标识属性的校验逻辑
问题背景
我有一个请求类,包含如下属性:
/// <summary> /// First time discount flag /// </summary> [JsonProperty("firstTimeDiscountFlag")] public string FirstTimeDiscountFlag { get; set; }
目前我通过以下代码检查该属性是否为空以及是否为允许的值(Y/N):
if(string.IsNullOrWhiteSpace(request.FirstTimeDiscountFlag) || (request.FirstTimeDiscountFlag.ToUpper() != "Y" && request.FirstTimeDiscountFlag.ToUpper() != "N"))
请问是否有更优的处理方式?
优化方案
1. 改用枚举类型(最推荐)
直接将字符串属性替换为枚举类型,从根源上杜绝非法值输入,同时提升代码可读性和类型安全性:
public enum DiscountFlag { [JsonProperty("Y")] Yes, [JsonProperty("N")] No } // 修改请求类属性类型 public DiscountFlag FirstTimeDiscountFlag { get; set; }
序列化/反序列化时会自动映射Y/N到枚举值,非法值会直接触发反序列化异常,从数据入口就完成了校验。
2. 封装可复用的校验方法
如果暂时无法修改属性类型,可将校验逻辑封装为独立方法,提升代码复用性和可读性:
public static bool IsValidDiscountFlag(string flag) { return !string.IsNullOrWhiteSpace(flag) && flag.Equals("Y", StringComparison.OrdinalIgnoreCase) || flag.Equals("N", StringComparison.OrdinalIgnoreCase); } // 调用示例 if (!IsValidDiscountFlag(request.FirstTimeDiscountFlag)) { // 非法值处理逻辑 }
使用StringComparison.OrdinalIgnoreCase比ToUpper()更高效,还能避免文化差异导致的判断误差。
3. 用集合存储允许值(适合可扩展场景)
如果后续允许值可能增加,用HashSet存储合法值会让扩展更灵活:
private static readonly HashSet<string> ValidDiscountFlags = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "Y", "N" }; // 校验逻辑 if (string.IsNullOrWhiteSpace(request.FirstTimeDiscountFlag) || !ValidDiscountFlags.Contains(request.FirstTimeDiscountFlag)) { // 非法值处理逻辑 }
HashSet的查找效率为O(1),后续新增允许值只需往集合中添加元素即可。
4. 结合数据注解自动校验(ASP.NET Core场景)
如果是ASP.NET Core项目,可通过数据注解在属性上直接标记校验规则,配合框架的模型验证自动生效:
[JsonProperty("firstTimeDiscountFlag")] [Required(ErrorMessage = "FirstTimeDiscountFlag cannot be empty")] [RegularExpression(@"^[YN]$", ErrorMessage = "FirstTimeDiscountFlag must be Y or N")] public string FirstTimeDiscountFlag { get; set; }
模型绑定阶段会自动完成校验,无需手动编写if判断逻辑。
内容的提问来源于stack exchange,提问作者MAK
相关产品推荐
相关产品推荐

