C#:多数据模型与辅助类代码重复缩减方案咨询
当然可以!这种重复写相同逻辑的场景,正好用**泛型(Generics)**来解决——它能让你写出一次定义、多处复用的类型安全方法,彻底告别每个辅助类里的重复代码,同时还能保证各个辅助类传入对应模型时得到正确的结果。
核心思路:用泛型抽象通用逻辑
泛型的本质是让方法/类能适配任意类型,同时保留类型检查。你可以把所有辅助类里的重复操作,抽成一个通用的泛型方法,然后让各个业务辅助类直接调用这个方法即可。
具体实现示例
第一步:创建通用工具类/方法
先写一个包含泛型方法的静态工具类(如果需要依赖注入,也可以做成非静态的,后面会提到),把你的重复操作逻辑放在这里:
public static class GenericModelProcessor { // 泛型方法:T代表任意模型类型,约束确保T是可实例化的引用类型 public static List<T> ProcessModelList<T>(T modelTemplate, List<T> inputList) where T : class, new() { var processedList = new List<T>(); // 这里写你所有辅助类都重复的操作逻辑 // 比如属性映射、数据验证、业务规则处理等 foreach (var item in inputList) { var processedItem = new T(); // 示例:手动复制属性(如果用AutoMapper会更简洁) processedItem.Id = item.Id; // 假设所有模型都有Id属性 processedItem.CreatedTime = DateTime.Now; // 通用的时间赋值逻辑 // 其他通用操作... processedList.Add(processedItem); } return processedList; } }
第二步:业务辅助类调用通用方法
现在每个业务辅助类不需要重复写逻辑,直接调用上面的泛型方法就行,泛型会自动推断出对应的模型类型:
// 示例模型:User public class UserModel { public int Id { get; set; } public string Username { get; set; } public DateTime CreatedTime { get; set; } } // User对应的辅助类 public class UserHelper { public List<UserModel> ProcessUsers(UserModel template, List<UserModel> userList) { // 直接调用通用方法,自动匹配T为UserModel var result = GenericModelProcessor.ProcessModelList(template, userList); // 如果User有专属的额外逻辑,在这里补充即可 result.ForEach(u => u.Username = u.Username.ToUpper()); return result; } } // 另一个示例模型:Product public class ProductModel { public int Id { get; set; } public string ProductName { get; set; } public DateTime CreatedTime { get; set; } } // Product对应的辅助类 public class ProductHelper { public List<ProductModel> ProcessProducts(ProductModel template, List<ProductModel> productList) { // 同样调用通用方法,自动匹配T为ProductModel return GenericModelProcessor.ProcessModelList(template, productList); } }
进阶优化:配合接口/依赖注入
如果你的模型有通用的行为(比如初始化、验证),可以定义一个接口来约束泛型,让通用逻辑更灵活:
// 定义通用模型接口 public interface IBaseModel { void Initialize(); } // 让所有模型实现这个接口 public class UserModel : IBaseModel { public int Id { get; set; } public string Username { get; set; } public DateTime CreatedTime { get; set; } public void Initialize() { CreatedTime = DateTime.Now; } } // 更新通用方法的约束,增加接口约束 public static List<T> ProcessModelList<T>(T modelTemplate, List<T> inputList) where T : class, IBaseModel, new() { var processedList = new List<T>(); foreach (var item in inputList) { var processedItem = new T(); processedItem.Initialize(); // 调用接口定义的通用方法 // 其他通用操作... processedList.Add(processedItem); } return processedList; }
如果你的项目用了依赖注入(比如需要注入AutoMapper、数据库上下文等),可以把通用类做成非静态的,通过构造函数注入依赖:
public class GenericModelProcessor<T> where T : class, IBaseModel, new() { private readonly IMapper _mapper; // 通过构造函数注入依赖 public GenericModelProcessor(IMapper mapper) { _mapper = mapper; } public List<T> ProcessModelList(T modelTemplate, List<T> inputList) { // 用AutoMapper简化属性映射 return inputList.Select(item => _mapper.Map<T>(item)).ToList(); } } // 在Startup.cs中注册泛型服务 services.AddScoped(typeof(GenericModelProcessor<>)); // 在业务辅助类中注入使用 public class UserHelper { private readonly GenericModelProcessor<UserModel> _userProcessor; public UserHelper(GenericModelProcessor<UserModel> userProcessor) { _userProcessor = userProcessor; } public List<UserModel> ProcessUsers(UserModel template, List<UserModel> userList) { return _userProcessor.ProcessModelList(template, userList); } }
总结
用泛型可以完美解决你的重复代码问题:
- 把通用逻辑抽成泛型方法,只维护一次
- 业务辅助类只需调用泛型方法,可灵活添加专属逻辑
- 通过泛型约束保证类型安全,避免编译错误
内容的提问来源于stack exchange,提问作者Mohammed Imthathullah




