繁体   English   中英

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

[英]How do you pass multiple enum values in 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 关于枚举类型的文档


编辑以回应问题的补充。

您将无法按原样使用该枚举,除非您想执行诸如将其作为数组/集合/参数数组传递之类的操作。 那会让你传递多个值。 标志语法要求将 Enum 指定为标志(或以非设计的方式对语言进行混蛋)。

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

我支持 Reed 的回答。 但是,在创建枚举时,您必须为每个枚举成员指定值,使其成为一种位字段。 例如:

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

否则,您可以创建自己的[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");

Reed Copsey 是正确的,如果可以,我会添加到原始帖子中,但我不能,所以我必须回复。

在任何旧的枚举上只使用 [Flags] 是危险的。 我相信您必须在使用标志时将枚举值显式更改为 2 的幂,以避免值发生冲突。 请参阅FlagsAttribute 和 Enum指南

在发布的答案和这些的帮助下:

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

我觉得我理解得很好。

谢谢。

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

[Flags]
public enum SomeName
{
    Name1,
    Name2
}

public class SomeClass()
{
    public void SomeMethod(SomeName enumInput)
    {
        ...
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM