如何遵循SOLID与DRY原则合并C#重复验证函数?
合并重复验证函数,遵循SOLID与DRY原则的正确实现
嘿,我来帮你搞定这个重复代码的问题!你之前尝试合并函数时遇到的问题,核心原因是Parfumes和Cosmetics是两个独立的类型,没有共同的抽象层,所以无法直接把它们的列表赋值给同一个变量。咱们用接口+泛型的方案就能完美解决,同时严格遵循SOLID和DRY原则。
步骤1:定义通用接口
首先,创建一个包含Id属性的接口,让两个实体类都实现它:
public interface IHasId { string Id { get; } }
步骤2:让实体类实现接口
修改你的Parfumes和Cosmetics类,实现上面的接口(假设它们原本就有Id属性):
public class Parfumes : IHasId { // 保留原有属性,只需实现IHasId接口 public string Id { get; set; } // 其他属性... } public class Cosmetics : IHasId { // 保留原有属性,只需实现IHasId接口 public string Id { get; set; } // 其他属性... }
步骤3:重构通用验证函数
现在可以写出一个通用的验证函数,用泛型约束限制输入类型必须实现IHasId,这样就能处理任何符合要求的列表:
using System.Text.RegularExpressions; using System.Collections.Generic; public static class ValidationHelper { public static bool IsStyleValid<T>(string style, List<T> items) where T : IHasId { // 处理空列表的情况,可根据业务需求调整返回值 if (items == null || items.Count == 0) return true; foreach (var item in items) { // 预编译正则表达式会更高效,这里为了保持和原代码一致先直接写 bool matchDecimal = Regex.IsMatch(item.Id, @"^(\d*\.)\d+$"); bool matchFullNumber = Regex.IsMatch(item.Id, @"^\d+$"); bool matchFraction = Regex.IsMatch(item.Id, @"^[1-9][0-9]*\/[1-9][0-9]*$"); // 用switch表达式让逻辑更清晰 bool isValid = style switch { "decimal" => matchDecimal, "full" => matchFullNumber, "numbersWithHalfs" => matchFraction, _ => false // 未知的style默认视为无效,可根据需求修改 }; if (!isValid) return false; } return true; } }
调用示例
现在你可以用同一个函数验证两种不同类型的列表了:
// 验证香水列表 List<Parfumes> myParfumes = new List<Parfumes>(); bool parfumesValid = ValidationHelper.IsStyleValid("decimal", myParfumes); // 验证化妆品列表 List<Cosmetics> myCosmetics = new List<Cosmetics>(); bool cosmeticsValid = ValidationHelper.IsStyleValid("numbersWithHalfs", myCosmetics);
额外优化建议
如果这个验证逻辑会被频繁调用,建议预编译正则表达式来提升性能:
// 在类级别预编译正则 private static readonly Regex DecimalRegex = new Regex(@"^(\d*\.)\d+$", RegexOptions.Compiled); private static readonly Regex FullNumberRegex = new Regex(@"^\d+$", RegexOptions.Compiled); private static readonly Regex FractionRegex = new Regex(@"^[1-9][0-9]*\/[1-9][0-9]*$", RegexOptions.Compiled); // 验证时直接使用预编译的实例 bool matchDecimal = DecimalRegex.IsMatch(item.Id);
内容的提问来源于stack exchange,提问作者Jessika Parker
相关产品推荐
相关产品推荐

