转换"周串"枚举

时间:2016-12-19 13:33:46

标签: c# parsing enums data-conversion

我目前正在处理从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'作为值。

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

3 个答案:

答案 0 :(得分:2)

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

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

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

答案 1 :(得分: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;

返回枚举:星期一,星期二,星期三。

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

答案 2 :(得分:1)

正如其他人已经说过的那样,您需要使用[Flags]上的enum属性,并将值设为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
    }