如何在C#中传递多个枚举值?
有时在阅读别人的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件事?
当你定义枚举时,只需用[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) { ... } }
借助已发布的答案和这些:
- FlagsAttribute类 (查看使用和不使用[Flags]属性的比较)
- 枚举标志属性
我觉得我很了解。
谢谢。