将 "weekstring" 转换为枚举

Converting "weekstring" to enum

我目前正在处理一些从 SQL-数据库安排的自动化作业。

每个作业作为 'RunDays' 类型的列 string(nvarchar(7))

假设值是 '1111111',这意味着 'SMTWTFS'(星期日,星期一,[...])。

我创建了这个枚举:

public enum RunDays : int
{
    Sunday = 0, 
    Monday = 1,
    Tuesday = 2,
    Wednesday = 3,
    Thrusday = 4, 
    Friday = 5, 
    Saturday = 6     

    //Maybe int is bad here cause Wednesday = 3 & Monday + Tuesday is also 3 -.-      
}

但是如何转换成那个,反之亦然?

这是我到目前为止尝试过的:

if(row["RunDays"] != DBNull.Value)
{
   for(int i = 0; i < row["RunDays"].ToString().Length; i++)
   {
      if(int.Parse(row["RunDays"].ToString()[i].ToString()) == 1)
      {
          job.RunDays = job.RunDays | (RunDays)i;
      }                            
   }
}

遗憾的是,我得到的只是 'Sunday' 作为值。

我做错了什么/我错过了什么?

如果您想要多个枚举值,您需要一个标有 [Flags] 属性的枚举,并为每个成员指定一个 2 的幂值:

[Flags]
public enum RunDays : int
{
    Sunday = 1, 
    Monday = 2,
    Tuesday = 4,
    Wednesday = 8,
    Thrusday = 16, 
    Friday = 32, 
    Saturday = 64          
}

[Flags] 属性使枚举能够采用未明确声明的值(例如 5),并且 2 的幂确保每个组合都是唯一的。

以下枚举可以满足您的需求:

[Flags]
public enum RunDays : int
{
   Sunday = 1, 
   Monday = 2,
   Tuesday = 4,
   Wednesday = 8,
   Thrusday = 16, 
   Friday = 32, 
   Saturday = 64     
}

请注意,枚举具有属性 [Flags],表明枚举可以被视为位域(一组标志)。此外,您必须以 2 的幂定义每个常数。 这个枚举可以有 1-128 范围内的值,描述了所有的可能性。 要使用枚举,您只需将整数值转换为您的枚举

RunDays days = (RunDays)14;

此 returns 枚举:星期一、星期二、星期三。

PS。值为 0 的星期日不是正确的值,因为在这种情况下,星期日的数字表示为 0,即默认整数值。因此,它可能会导致意想不到的结果。通常建议使用 None 或 Unknown 标签作为 0 值(如果你真的需要的话)。

正如其他人已经说过的,您需要在 enum 上使用 [Flags] 属性并将值设为 2 的幂,以便星期一+星期二!=星期三。使用 C# 7 的新 binary literals 功能使这特别方便:

[Flags]
enum RunDays
{
    None    =       0b00000000,
    Sunday =        0b00000010,
    Monday =        0b00000100,
    Tuesday =       0b00001000,
    Wednesday =     0b00010000,
    Thursday =      0b00100000,
    Friday =        0b01000000,
    Saturday =      0b10000000,
}

由于您的索引不再与 enum 值相同,您不能再进行转换;转换为数组是一种方法:

    static readonly List<RunDays> s_runDays = Enum.GetValues(typeof(RunDays)).Cast<RunDays>().ToList();
    static RunDays Parse(string s)
    {
        if (String.IsNullOrWhiteSpace(s)) throw new ArgumentNullException(nameof(s));
        if (s.Length != 7) throw new ArgumentOutOfRangeException(nameof(s));

        var retval = RunDays.None;
        for (int i = 0; i < s.Length; i++)
            if (Int32.TryParse(s[i].ToString(), out var result) && (result > 0))
                retval |= s_runDays[i+1];
        return retval;      
    }

这样,您现在就得到了想要的结果:

    static void Main(string[] args)
    {
        var monday = Parse("0100000"); // Monday
        var weekends = Parse("1000001");    // Sunday | Saturday
        var weekdays = Parse("0111110"); // Monday | Tuesday | Wednesday | Thursday | Friday
    }