Muhammad Kamran
Muhammad Kamran

Reputation: 101

How to check value with Enum Listing using C#

I am working on an application where I have implemented a functionality. The flow is like we are getting settings that can be 1 HOURS, 2 HOURS, 1 WEEK, 2 WEEKS or 1 MONTH. For Example, If I get Settings from Database like 1 HOUR then it will calculate the difference between two dates and check for 1 HOUR with the difference I am getting from the calculation. I have done it by using multiple IF checks but I want to optimize the code. Here is my implementation.

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;
        }

Is there any way to write optimized and less code to achieve the functionality? I am getting the same settings from the database as mentioned in the Enum description. That can be a single value every time. Always check will return true always.

Upvotes: 0

Views: 90

Answers (1)

JonasH
JonasH

Reputation: 36351

I would not recommend using enum values in this way. Let each enum value represent an arbitrary tag, that you separately convert to a duration with a extension method. For example:

        public static TimeSpan ToDuration(this TaskSchedulingEnum self)
        {
            return self switch
            {
                TaskSchedulingEnum.OneHour => TimeSpan.FromHours(1),
                TaskSchedulingEnum.TwoHours => TimeSpan.FromHours(2),
                TaskSchedulingEnum.OneDay => TimeSpan.FromDays(1),
                TaskSchedulingEnum.Always => Timeout.InfiniteTimeSpan,
            };
        }

Once you have a timespan to describe the duration it should be trivial to add this to any start time to get the end time or other similar operations.

Note that you might need special handling for the Always-value, since arithmetic operations with infinities will not work correctly. You might want to describe it with TimeSpan.MaxValue or use a TimeSpan? type instead, depending on how it is used.

Upvotes: 1

Related Questions