有时在阅读其他人的C#代码时,我会看到一个方法,它会在一个参数中接受多个枚举值。我一直以为它有点整洁,但从来没有考虑过它。
好吧,现在我想我可能需要它,但不知道如何
实现这种事情。
<小时/> 在我的特殊情况下,我想使用System.DayOfWeek,它被定义为:
[Serializable]
[ComVisible(true)]
public enum DayOfWeek
{
Sunday = 0,
Monday = 1,
Tuesday = 2,
Wednesday = 3,
Thursday = 4,
Friday = 5,
Saturday = 6
}
我希望能够将一个或多个DayOfWeek值传递给我的方法。我可以使用这个特殊的枚举吗?我如何做上面列出的3件事?
答案 0 :(得分:166)
当您定义枚举时,只需使用[Flags]属性,将值设置为2的幂,它将以这种方式工作。
除了将多个值传递给函数之外,没有其他任何更改。
例如:
[Flags]
enum DaysOfWeek
{
Sunday = 1,
Monday = 2,
Tuesday = 4,
Wednesday = 8,
Thursday = 16,
Friday = 32,
Saturday = 64
}
public void RunOnDays(DaysOfWeek days)
{
bool isTuesdaySet = (days & DaysOfWeek.Tuesday) == DaysOfWeek.Tuesday;
if (isTuesdaySet)
//...
// Do your work here..
}
public void CallMethodWithTuesdayAndThursday()
{
this.RunOnDays(DaysOfWeek.Tuesday | DaysOfWeek.Thursday);
}
有关详细信息,请参阅MSDN's documentation on Enumeration Types。
编辑以回应对问题的补充。
除非您想要将其作为数组/集合/ params数组传递,否则您将无法按原样使用该枚举。那会让你传递多个值。 flags语法要求将Enum指定为标志(或者以未设计的方式对语言进行标准化)。
答案 1 :(得分:72)
我认为更优雅的解决方案是使用HasFlag():
[Flags]
public enum DaysOfWeek
{
Sunday = 1,
Monday = 2,
Tuesday = 4,
Wednesday = 8,
Thursday = 16,
Friday = 32,
Saturday = 64
}
public void RunOnDays(DaysOfWeek days)
{
bool isTuesdaySet = days.HasFlag(DaysOfWeek.Tuesday);
if (isTuesdaySet)
{
//...
}
}
public void CallMethodWithTuesdayAndThursday()
{
RunOnDays(DaysOfWeek.Tuesday | DaysOfWeek.Thursday);
}
答案 2 :(得分:23)
我是里德的第二个回答。但是,在创建枚举时,必须为每个枚举成员指定值,以使其成为一种位字段。例如:
[Flags]
public enum DaysOfWeek
{
Sunday = 1,
Monday = 2,
Tuesday = 4,
Wednesday = 8,
Thursday = 16,
Friday = 32,
Saturday = 64,
None = 0,
All = Weekdays | Weekend,
Weekdays = Monday | Tuesday | Wednesday | Thursday | Friday,
Weekend = Sunday | Saturday,
// etc.
}
答案 3 :(得分:11)
在我的特殊情况下,我愿意 喜欢使用System.DayOfWeek
您无法将System.DayOfWeek用作[Flags]
枚举,因为您无法控制它。如果您希望使用接受多个DayOfWeek
的方法,则必须使用params
关键字
void SetDays(params DayOfWeek[] daysToSet)
{
if (daysToSet == null || !daysToSet.Any())
throw new ArgumentNullException("daysToSet");
foreach (DayOfWeek day in daysToSet)
{
// if( day == DayOfWeek.Monday ) etc ....
}
}
SetDays( DayOfWeek.Monday, DayOfWeek.Sunday );
否则,您可以按照许多其他响应者的概述创建自己的[Flags]
枚举,并使用按位比较。
答案 4 :(得分:9)
[Flags]
public enum DaysOfWeek
{
Mon = 1,
Tue = 2,
Wed = 4,
Thur = 8,
Fri = 16,
Sat = 32,
Sun = 64
}
你必须指定数字,并像这样递增它们,因为它以按位方式存储值。
然后定义你的方法来获取这个枚举
public void DoSomething(DaysOfWeek day)
{
...
}
并称之为
DoSomething(DaysOfWeek.Mon | DaysOfWeek.Tue) // Both Monday and Tuesday
要检查是否包含其中一个枚举值,请使用按位操作(如
)进行检查public void DoSomething(DaysOfWeek day)
{
if ((day & DaysOfWeek.Mon) == DaysOfWeek.Mon) // Does a bitwise and then compares it to Mondays enum value
{
// Monday was passed in
}
}
答案 5 :(得分:3)
[Flags]
public enum DaysOfWeek{
Sunday = 1 << 0,
Monday = 1 << 1,
Tuesday = 1 << 2,
Wednesday = 1 << 3,
Thursday = 1 << 4,
Friday = 1 << 5,
Saturday = 1 << 6
}
以这种格式调用方法
MethodName(DaysOfWeek.Tuesday | DaysOfWeek.Thursday);
实现EnumToArray方法以获取传递的选项
private static void AddEntryToList(DaysOfWeek days, DaysOfWeek match, List<string> dayList, string entryText) {
if ((days& match) != 0) {
dayList.Add(entryText);
}
}
internal static string[] EnumToArray(DaysOfWeek days) {
List<string> verbList = new List<string>();
AddEntryToList(days, HttpVerbs.Sunday, dayList, "Sunday");
AddEntryToList(days, HttpVerbs.Monday , dayList, "Monday ");
...
return dayList.ToArray();
}
答案 6 :(得分:3)
使用[Flags]属性标记您的枚举。还要确保所有值都是互斥的(两个值不能相等),例如1,2,4,8,16,32,64
[Flags]
public enum DayOfWeek
{
Sunday = 1,
Monday = 2,
Tuesday = 4,
Wednesday = 8,
Thursday = 16,
Friday = 32,
Saturday = 64
}
如果您有一个接受DayOfWeek枚举的方法,请使用按位或运算符(|)将多个成员一起使用。例如:
MyMethod(DayOfWeek.Sunday|DayOfWeek.Tuesday|DayOfWeek.Friday)
要检查参数是否包含特定成员,请使用按位和运算符(&amp;)与要检查的成员。
if(arg & DayOfWeek.Sunday == DayOfWeek.Sunday)
Console.WriteLine("Contains Sunday");
答案 7 :(得分:2)
Reed Copsey是正确的,如果可以,我会添加到原始帖子,但我不能这样我将不得不回复。
在任何旧枚举上使用[Flags]都很危险。我相信你必须在使用标志时明确地将枚举值更改为2的幂,以避免值中的冲突。请参阅guidelines for FlagsAttribute and Enum。
答案 8 :(得分:0)
借助已发布的答案和以下内容:
我觉得我很清楚。
感谢。
答案 9 :(得分:-2)
这种性质的东西应该表明你在寻找什么:
[Flags]
public enum SomeName
{
Name1,
Name2
}
public class SomeClass()
{
public void SomeMethod(SomeName enumInput)
{
...
}
}