You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用C#枚举(Enum)优化时间设置校验逻辑?

优化日期差值校验代码实现

需求:根据数据库返回的「1 HOUR」「2 HOURS」「1 WEEK」等时间设置,计算两个日期的差值并校验是否匹配该设置。当前通过多个IF判断实现,希望精简优化代码。数据库返回的设置与Enum的Description一致,每次仅返回单个值,「ALWAYS」设置直接返回true。

原实现代码

public enum TaskSchedulingEnum : int
{
    [Description("1 HOUR")]
    OneHour = 1,
    [Description("2 HOURS")]
    TwoHours = 2,
    [Description("8 HOURS")]
    EightHours = 8,
    [Description("1 DAY")]
    OneDay = 1,
    [Description("3 DAYS")]
    ThreeDays = 3,
    [Description("1 WEEK")]
    OneWeek = 1,
    [Description("2 WEEKS")]
    TwoWeeks = 2,
    [Description("1 MONTH")]
    OneMonth = 1,
    [Description("ALWAYS")]
    Always = 14
}

private async Task<bool> GetUserSettings(string companyId, DateTime? TaskStartDateTime)
{
    // get company settings ... 
    var settings = await projulSettingsService.GetCompanyNotificationSettings(companyId, ProjulSettingsTypeEnum.Notifications);
    var scheduleSettings = string.Empty;
    if (settings.Where(x => x.Name == ProjulPortalSettings.GeneralSettingsNotificationIsDisabled).Select(x => x.Value).FirstOrDefault() == "false")
    {
        scheduleSettings = JsonConvert.DeserializeObject<string>(settings.Where(x => x.Name == ProjulPortalSettings.NotificationTaskAssignedImmediateWindow).Select(x => x.Value).FirstOrDefault());
        if (!string.IsNullOrEmpty(scheduleSettings))
        {
            var _timespan = (DateTime.UtcNow - TaskStartDateTime).Value;
            var difference = _timespan.TotalHours; // in hours..
            TimeSpan days = TimeSpan.FromHours(difference); // days..
            var weeks = (days.TotalDays % 365) / 7; // weeks 
            var months = (days.TotalDays % 365) / 30; // months

            var list = ApplicationExtensions.GetEnumList<TaskSchedulingEnum>().ToList();
            var _val = list.Where(x => x.Text == scheduleSettings).FirstOrDefault();

            if (scheduleSettings == TaskSchedulingEnum.OneHour.GetEnumDescrip()
                || scheduleSettings == TaskSchedulingEnum.TwoHours.GetEnumDescrip()
                || scheduleSettings == TaskSchedulingEnum.EightHours.GetEnumDescrip())
            {
                if (difference == Convert.ToDouble(_val.Value))
                    return true;
            }
            else if (scheduleSettings == TaskSchedulingEnum.OneDay.GetEnumDescrip()
                 || scheduleSettings == TaskSchedulingEnum.ThreeDays.GetEnumDescrip())
            {
                if (days.TotalDays == Convert.ToDouble(_val.Value))
                    return true;
            }
            else if (scheduleSettings == TaskSchedulingEnum.OneWeek.GetEnumDescrip()
                || scheduleSettings == TaskSchedulingEnum.TwoWeeks.GetEnumDescrip())
            {
                if (weeks == Convert.ToDouble(_val.Value))
                    return true;
            }
            else if (scheduleSettings == TaskSchedulingEnum.OneMonth.GetEnumDescrip())
            {
                if (months == Convert.ToDouble(_val.Value))
                    return true;
            }
            else if (scheduleSettings == TaskSchedulingEnum.Always.GetEnumDescrip())
            {
                return true;
            }
            return false;

        }
    }
    return false;
}

优化后的实现代码

// 枚举扩展方法:根据Description获取对应的枚举值
public static class EnumExtensions
{
    public static TaskSchedulingEnum GetTaskSchedulingEnumFromDescription(string description)
    {
        foreach (var field in typeof(TaskSchedulingEnum).GetFields())
        {
            if (Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute)) is DescriptionAttribute attr && 
                attr.Description == description)
            {
                return (TaskSchedulingEnum)field.GetValue(null);
            }
        }
        throw new ArgumentException($"无效的时间设置:{description}");
    }

    // 复用原有的GetEnumDescrip方法(如果已存在),这里补充实现示例
    public static string GetEnumDescrip(this TaskSchedulingEnum @enum)
    {
        var field = typeof(TaskSchedulingEnum).GetField(@enum.ToString());
        if (Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute)) is DescriptionAttribute attr)
        {
            return attr.Description;
        }
        return @enum.ToString();
    }
}

public enum TaskSchedulingEnum : int
{
    [Description("1 HOUR")]
    OneHour = 1,
    [Description("2 HOURS")]
    TwoHours = 2,
    [Description("8 HOURS")]
    EightHours = 8,
    [Description("1 DAY")]
    OneDay = 1,
    [Description("3 DAYS")]
    ThreeDays = 3,
    [Description("1 WEEK")]
    OneWeek = 1,
    [Description("2 WEEKS")]
    TwoWeeks = 2,
    [Description("1 MONTH")]
    OneMonth = 1,
    [Description("ALWAYS")]
    Always = 14
}

private async Task<bool> GetUserSettings(string companyId, DateTime? taskStartDateTime)
{
    // 边界判断:任务开始时间为空直接返回false
    if (!taskStartDateTime.HasValue)
        return false;

    var settings = await projulSettingsService.GetCompanyNotificationSettings(companyId, ProjulSettingsTypeEnum.Notifications);
    
    // 通知禁用则返回false
    var isDisabled = settings.FirstOrDefault(x => x.Name == ProjulPortalSettings.GeneralSettingsNotificationIsDisabled)?.Value == "true";
    if (isDisabled)
        return false;

    // 获取并解析时间设置
    var scheduleSettingJson = settings.FirstOrDefault(x => x.Name == ProjulPortalSettings.NotificationTaskAssignedImmediateWindow)?.Value;
    if (string.IsNullOrEmpty(scheduleSettingJson))
        return false;

    var scheduleSettings = JsonConvert.DeserializeObject<string>(scheduleSettingJson);
    if (string.IsNullOrEmpty(scheduleSettings))
        return false;

    // ALWAYS设置直接返回true
    if (scheduleSettings == TaskSchedulingEnum.Always.GetEnumDescrip())
        return true;

    // 转换为枚举值
    var scheduleEnum = EnumExtensions.GetTaskSchedulingEnumFromDescription(scheduleSettings);
    var timeDiff = DateTime.UtcNow - taskStartDateTime.Value;

    // 用字典映射枚举到校验逻辑,消除冗余IF
    var validationRules = new Dictionary<TaskSchedulingEnum, Func<TimeSpan, bool>>
    {
        { TaskSchedulingEnum.OneHour, ts => ts.TotalHours == 1 },
        { TaskSchedulingEnum.TwoHours, ts => ts.TotalHours == 2 },
        { TaskSchedulingEnum.EightHours, ts => ts.TotalHours == 8 },
        { TaskSchedulingEnum.OneDay, ts => ts.TotalDays == 1 },
        { TaskSchedulingEnum.ThreeDays, ts => ts.TotalDays == 3 },
        { TaskSchedulingEnum.OneWeek, ts => ts.TotalDays / 7 == 1 },
        { TaskSchedulingEnum.TwoWeeks, ts => ts.TotalDays / 7 == 2 },
        { TaskSchedulingEnum.OneMonth, ts => ts.TotalDays / 30 == 1 }
    };

    return validationRules.TryGetValue(scheduleEnum, out var validator) ? validator(timeDiff) : false;
}

优化核心要点

  • 消除冗余IF判断:用字典映射枚举值到对应的差值校验逻辑,新增时间设置只需在字典中添加条目,维护成本更低。
  • 简化枚举转换:通过扩展方法直接根据Description获取枚举值,避免遍历列表查找,代码更高效。
  • 提前边界判断:对空值、通知禁用、配置为空等情况提前返回,减少嵌套层级,提升代码可读性。
  • 移除冗余计算:原代码中多余的中间变量(如weeks、months)直接整合到校验逻辑中,避免不必要的计算。
  • 规范命名:调整变量名符合C#命名规范,提升代码可读性。

内容的提问来源于stack exchange,提问作者Muhammad Kamran

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 09:33:15