代码重构:简化DaysDetails的ConstructDays方法以提升可维护性
重构ConstructDays方法的优化方案
嘿,我来给你梳理几个能让这个ConstructDays方法更简洁、更易维护的优化方向,顺便还能修复原方法里的隐藏bug:
1. 用映射集合替代重复的if判断(最直接的优化)
原方法里写了7个几乎一模一样的if判断,不仅冗余,后续修改或者调整顺序都要改一堆代码。我们可以把星期属性和对应的数字做成一个映射集合,遍历集合来筛选选中的天数,再用string.Join直接生成逗号分隔的字符串——这玩意儿会自动处理分隔符,完全不用手动折腾逗号或者StringBuilder的拼接逻辑。
而且原方法还有个隐藏bug:当多个天被选中时,它会直接把数字连在一起(比如选中周日+周一,会输出"01"而不是预期的"0,1"),用string.Join能完美解决这个问题。
重构后的代码:
public string ConstructDays(DaysDetails d) { // 定义星期属性与对应数字的映射 var dayMappings = new List<(bool IsSelected, int DayNumber)> { (d.Sun, 0), (d.Mon, 1), (d.Tue, 2), (d.Wed, 3), (d.Thu, 4), (d.Fri, 5), (d.Sat, 6) }; // 筛选选中的天数,转成字符串后用逗号拼接 var selectedDays = dayMappings .Where(m => m.IsSelected) .Select(m => m.DayNumber.ToString()); return string.Join(",", selectedDays); }
2. 用Flags枚举替代冗余的布尔属性(更符合C#最佳实践)
如果业务场景允许,完全可以把DaysDetails这个DTO换成带[Flags]特性的枚举,这样不仅能简化数据结构(不用写7个布尔属性),还能让天数的选中、组合操作更简洁。
先定义枚举:
[Flags] public enum DaysOfWeek { None = 0, Sunday = 1 << 0, // 对应数字0 Monday = 1 << 1, // 对应数字1 Tuesday = 1 << 2, // 对应数字2 Wednesday = 1 << 3, Thursday = 1 << 4, Friday = 1 << 5, Saturday = 1 << 6 }
然后重构ConstructDays方法:
public string ConstructDays(DaysOfWeek selectedDays) { return string.Join(",", Enum.GetValues<DaysOfWeek>() .Where(day => day != DaysOfWeek.None && selectedDays.HasFlag(day)) // 计算每个枚举值对应的序号(也可以给枚举加特性存序号,更直观) .Select(day => (int)Math.Log2((int)day))); }
使用的时候也更方便:比如要选中周日和周一,直接写var selected = DaysOfWeek.Sunday | DaysOfWeek.Monday;,比操作7个布尔属性清爽多了。
3. 提取复用逻辑,让代码更规范
如果这个天数映射逻辑会在多个地方用到,可以把映射集合做成静态只读的,或者直接把ConstructDays方法放到DaysDetails类内部,让职责更单一,调用也更方便:
public class DaysDetails { public bool Sun { get; set; } public bool Mon { get; set; } public bool Tue { get; set; } public bool Wed { get; set; } public bool Thu { get; set; } public bool Fri { get; set; } public bool Sat { get; set; } // 静态映射集合,全局复用,不用每次创建新集合 private static readonly List<(Func<DaysDetails, bool> IsSelected, int DayNumber)> _dayMappings = new() { (d => d.Sun, 0), (d => d.Mon, 1), (d => d.Tue, 2), (d => d.Wed, 3), (d => d.Thu, 4), (d => d.Fri, 5), (d => d.Sat, 6) }; public string ConstructDays() { var selectedDays = _dayMappings .Where(m => m.IsSelected(this)) .Select(m => m.DayNumber.ToString()); return string.Join(",", selectedDays); } }
调用时直接用daysDetails.ConstructDays()就行,不用再传参数,代码更简洁。
内容的提问来源于stack exchange,提问作者user1400915
相关产品推荐
相关产品推荐

