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

发布于 2024-07-25 16:02:03 字数 594 浏览 5 评论 0原文

有时,在阅读其他人的 C# 代码时,我会看到一种方法在单个参数中接受多个枚举值。 我一直以为它很整洁,但从未仔细研究过。

好吧,现在我想我可能需要它,但不知道如何

  1. 设置方法签名来接受这项
  2. 工作,并使用方法中的值
  3. 定义枚举

来实现此类事情。


In my particular situation, I would like to use the System.DayOfWeek, which is defined as:

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

我希望能够将一个或多个 DayOfWeek 值传递给我的方法。 我可以按原样使用这个特定的枚举吗? 我该如何做上面列出的 3 件事?

Sometimes when reading others' C# code I see a method that will accept multiple enum values in a single parameter. I always thought it was kind of neat, but never looked into it.

Well, now I think I may have a need for it, but don't know how to

  1. set up the method signature to accept this
  2. work with the values in the method
  3. define the enum

to achieve this sort of thing.


In my particular situation, I would like to use the System.DayOfWeek, which is defined as:

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

I want to be able to pass one or more of the DayOfWeek values to my method. Will I be able to use this particular enum as it is? How do I do the 3 things listed above?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

心病无药医 2024-08-01 16:02:04

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

I think the more elegant solution is to use 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);
    }
滥情哥ㄟ 2024-08-01 16:02:04

我赞同里德的回答。 但是,在创建枚举时,您必须指定每个枚举成员的值,以便它形成一种位字段。 例如:

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

I second Reed's answer. However, when creating the enum, you must specify the values for each enum member so it makes a sort of bit field. For example:

[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.
}
人生戏 2024-08-01 16:02:04

在我的特殊情况下,我会
喜欢使用 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]许多其他响应者概述的枚举并使用按位比较。

In my particular situation, I would
like to use the System.DayOfWeek

You can not use the System.DayOfWeek as a [Flags] enumeration because you have no control over it. If you wish to have a method that accepts multiple DayOfWeek then you will have to use the params keyword

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

Otherwise you can create your own [Flags] enumeration as outlined by numerous other responders and use bitwise comparisons.

っ〆星空下的拥抱 2024-08-01 16:02:04
[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
{
  Mon = 1,
  Tue = 2,
  Wed = 4,
  Thur = 8,
  Fri = 16,
  Sat = 32,
  Sun = 64
}

You have to specify the numbers, and increment them like this because it is storing the values in a bitwise fashion.

Then just define your method to take this enum

public void DoSomething(DaysOfWeek day)
{
  ...
}

and to call it do something like

DoSomething(DaysOfWeek.Mon | DaysOfWeek.Tue) // Both Monday and Tuesday

To check if one of the enum values was included check them using bitwise operations like

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
  }
}
千秋岁 2024-08-01 16:02:04
[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]
public enum DaysOfWeek{
    Sunday = 1 << 0,
    Monday = 1 << 1,
    Tuesday = 1 << 2,
    Wednesday = 1 << 3,
    Thursday = 1 << 4,
    Friday = 1 << 5,
    Saturday = 1 << 6
}

Call the method in this format

MethodName(DaysOfWeek.Tuesday | DaysOfWeek.Thursday);

Implement a EnumToArray method to get the options passed

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();
}
ま柒月 2024-08-01 16:02:04

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

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

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

Mark your enum with the [Flags] attribute. Also ensure that all of your values are mutually exclusive (two values can't add up to equal another) like 1,2,4,8,16,32,64 in your case

[Flags]
public enum DayOfWeek
{ 
Sunday = 1,   
Monday = 2,   
Tuesday = 4,   
Wednesday = 8,   
Thursday = 16,   
Friday = 32,    
Saturday = 64
}

When you have a method that accepts a DayOfWeek enum use the bitwise or operator (|) to use multiple members together. For example:

MyMethod(DayOfWeek.Sunday|DayOfWeek.Tuesday|DayOfWeek.Friday)

To check if the parameter contains a specific member, use the bitwise and operator (&) with the member you are checking for.

if(arg & DayOfWeek.Sunday == DayOfWeek.Sunday)
Console.WriteLine("Contains Sunday");
等数载,海棠开 2024-08-01 16:02:04

里德·科普西(Reed Copsey)是正确的,如果可以的话,我会添加到原始帖子中,但我不能,所以我必须回复。

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

Reed Copsey is correct and I would add to the original post if I could, but I cant so I'll have to reply instead.

Its dangerous to just use [Flags] on any old enum. I believe you have to explicitly change the enum values to powers of two when using flags, to avoid clashes in the values. See the guidelines for FlagsAttribute and Enum.

浅笑依然 2024-08-01 16:02:04

借助发布的答案和这些:

  1. FlagsAttribute Class (看一下使用和不使用[Flags]属性的比较)
  2. Enum Flags Attribute

我感觉我很明白。

谢谢。

With the help of the posted answers and these:

  1. FlagsAttribute Class (Look at the comparison of using and not using the [Flags] attribute)
  2. Enum Flags Attribute

I feel like I understand it pretty well.

Thanks.

§对你不离不弃 2024-08-01 16:02:04

这种性质的东西应该表明您正在寻找什么:

[Flags]
public enum SomeName
{
    Name1,
    Name2
}

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

Something of this nature should show what you are looking for:

[Flags]
public enum SomeName
{
    Name1,
    Name2
}

public class SomeClass()
{
    public void SomeMethod(SomeName enumInput)
    {
        ...
    }
}
鼻尖触碰 2024-08-01 16:02:03

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


编辑以回应问题的补充。

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

When you define the enum, just attribute it with [Flags], set values to powers of two, and it will work this way.

Nothing else changes, other than passing multiple values into a function.

For example:

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

For more details, see MSDN's documentation on Enumeration Types.


Edit in response to additions to question.

You won't be able to use that enum as is, unless you wanted to do something like pass it as an array/collection/params array. That would let you pass multiple values. The flags syntax requires the Enum to be specified as flags (or to bastardize the language in a way that's its not designed).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文