将 "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
}
我目前正在处理一些从 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
}