簡體   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