如何在C#中传递多个枚举值?

有时在阅读别人的C#代码时,我看到一个方法将接受多个枚举值在一个单一的参数。 我一直认为这是一种整洁,但从来没有看过它。

那么现在我想我可能有这个需要,但是不知道如何去做

  1. 设置方法签名来接受这个
  2. 使用方法中的值
  3. 定义枚举

实现这样的事情。


在我的特殊情况下,我想使用System.DayOfWeek,它被定义为:

[Serializable] [ComVisible(true)] public enum DayOfWeek { Sunday = 0, Monday = 1, Tuesday = 2, Wednesday = 3, Thursday = 4, Friday = 5, Saturday = 6 } 

我希望能够将一个或多个DayOfWeek值传递给我的方法。 我将能够使用这个特定的枚举吗? 我如何做上述3件事?

当你定义枚举时,只需用[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有关枚举types的文档 。


编辑回应添加问题。

你将不能使用这个枚举,除非你想做一些像传递数组/数据/参数数组一样的东西。 这将让你通过多个值。 flags语法要求将Enum指定为标志(或者以未devise的方式混杂该语言)。

我认为更优雅的解决scheme是使用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); } 

我是第二个里德的回答。 但是,在创build枚举时,您必须为每个枚举成员指定值,以便创build一个位域。 例如:

 [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. } 

在我的特殊情况下,我想使用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 ); 

否则,您可以创build您自己的[Flags]枚举,如许多其他响应者所述,并使用按位比较。

 [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 } } 
 [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(); } 

用[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) 

要检查参数是否包含特定成员,请使用按位运算符(&)和您正在检查的成员。

 if(arg & DayOfWeek.Sunday == DayOfWeek.Sunday) Console.WriteLine("Contains Sunday"); 

里德·科普塞是正确的,我会添加到原来的post,如果我可以,但我不能,所以我不得不回答。

在任何旧的枚举上使用[Flags]都是危险的。 我相信在使用标志时,必须明确地将枚举值更改为两个幂,以避免值中的冲突。 请参阅FlagsAttribute和Enum的指导原则 。

这种性质的东西应该显示你在找什么:

 [Flags] public enum SomeName { Name1, Name2 } public class SomeClass() { public void SomeMethod(SomeName enumInput) { ... } } 

借助已发布的答案和这些:

  1. FlagsAttribute类 (查看使用和不使用[Flags]属性的比较)
  2. 枚举标志属性

我觉得我很了解。

谢谢。