70

我知道我可以成倍增加,但我不想做懒惰的编程。

有没有人设计了一些魔法来自动将枚举编号为 2 的幂?

这是我要使其具体化的示例:

[Flags]
private enum Targets : uint
{
    None = 0,
    Campaigns = 1,
    CampaignGroups = 2,
    Advertisers = 4,
    AdvertiserGroups = 8,
    AffiliateGroups = 16,
    Affiliates = 32,
    Creatives = 64,
    DetailedLeads = 128,
    DetailedSales = 256,
    ProgramLeads = 512,
    CreativeDeployments = 1024,
    CampaignCategories = 2048,
    Payouts = 4096,
    All = uint.MaxValue
}
4

6 回答 6

126

将值写为移位位并让编译器进行数学运算:

[Flags]
private enum Targets : uint
{
    None                = 0,
    Campaigns           = 1,
    CampaignGroups      = 2 << 0,
    Advertisers         = 2 << 1,
    AdvertiserGroups    = 2 << 2,
    AffiliateGroups     = 2 << 3,
    Affiliates          = 2 << 4,
    Creatives           = 2 << 5,
    DetailedLeads       = 2 << 6,
    DetailedSales       = 2 << 7,
    ProgramLeads        = 2 << 8,
    CreativeDeployments = 2 << 9,
    CampaignCategories  = 2 << 10,
    Payouts             = 2 << 11,
    // etc.
}

詹姆斯的建议也不错。事实上,我更喜欢这种方式。你也可以这样写:

[Flags]
private enum Targets : uint
{
    None                = 0,
    Campaigns           = 1 << 0,
    CampaignGroups      = 1 << 1,
    Advertisers         = 1 << 2,
    AdvertiserGroups    = 1 << 3,
    AffiliateGroups     = 1 << 4,
    // etc.
}
于 2012-05-11T21:08:06.940 回答
43

使用十六进制表示法也比十进制表示法简单一些(不需要计算器):

[Flags]
private enum Targets : uint
{
    None                = 0,
    Campaigns           = 0x01,
    CampaignGroups      = 0x02,
    Advertisers         = 0x04,
    AdvertiserGroups    = 0x08,
    AffiliateGroups     = 0x10,
    Affiliates          = 0x20,
    Creatives           = 0x40,
    DetailedLeads       = 0x80,
    DetailedSales       = 0x100,
    ProgramLeads        = 0x200,
    CreativeDeployments = 0x400,
    CampaignCategories  = 0x800,
    Payouts             = 0x1000,
    // and the pattern of doubling continues
    // 0x2000
    // 0x4000
    // 0x8000
    // 0x10000
}

不像 Cody 和 James 的解决方案那样优雅,但不需要计算器。

于 2012-05-11T21:10:21.963 回答
8

快进五年后,从 C# 7.0 开始,您可以使用新的数字二进制文字来简化枚举标志声明。

[Flags]
private enum Targets : uint
{
    None = 0,
    Campaigns =             0b0000_0000_0000_0001,
    CampaignGroups =        0b0000_0000_0000_0010,
    Advertisers =           0b0000_0000_0000_0100,
    AdvertiserGroups =      0b0000_0000_0000_1000,
    AffiliateGroups =       0b0000_0000_0001_0000,
    Affiliates =            0b0000_0000_0010_0000,
    Creatives =             0b0000_0000_0100_0000,
    DetailedLeads =         0b0000_0000_1000_0000,
    DetailedSales =         0b0000_0001_0000_0000,
    ProgramLeads =          0b0000_0010_0000_0000,
    CreativeDeployments =   0b0000_0100_0000_0000,
    CampaignCategories =    0b0000_1000_0000_0000,
    Payouts =               0b0001_0000_0000_0000,
    All = uint.MaxValue
}

https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-7#numeric-literal-syntax-improvements

于 2017-11-21T11:23:03.523 回答
2

我执行以下操作:

 using System;

 [Flags]
 public enum AnimalCharacteristics : long
 {
     Tail = 1 << AnimalCharacteristicsBitPositions.Tail,
     Eyes = 1 << AnimalCharacteristicsBitPositions.Eyes,
     Furry = 1 << AnimalCharacteristicsBitPositions.Furry,
     Bipedal = 1 << AnimalCharacteristicsBitPositions.Bipedal
 }

 internal enum AnimalCharacteristicsBitPositions : int
 {
     Tail = 0,
     Eyes,
     Furry,
     Bipedal
 }

 public class Program
 {
     public static void Main()
     {
         var human = AnimalCharacteristics.Eyes | AnimalCharacteristics.Bipedal;
         var dog = AnimalCharacteristics.Eyes | AnimalCharacteristics.Tail | AnimalCharacteristics.Furry;

         Console.WriteLine($"Human: {human} ({(long)human})");
         Console.WriteLine($"Dog: {dog} ({(long)dog})");
     }
 }

这样做的好处是,您可以轻松地重新排序条目并添加新条目,只需按照模式将它们放入两个枚举中即可。位位置取决于第二个枚举。要跳过位位置,您只需在第二个枚举中的任意位置分配一个数字,编译器将从那里继续计数。

请注意,这些位置比实际位位置少一(如果您将最低有效位位置称为 1)。当然,您可以从 1 开始,如果您愿意,可以从第一个枚举中的位移位中减去 1。

于 2019-08-29T00:16:54.213 回答
0

这是另一种替代方法:

[Flags]
public enum COURSECOMPONENT_T : int
{
    Everything = -1,
    Nothing = 0,
    AttendanceRegisters = 1,
    Checklists = 2 * AttendanceRegisters,
    Competencies = 2 * Checklists,
    Content = 2 * Competencies,
    CourseFiles = 2 * Content,
    Discussions = 2 * CourseFiles,
    DisplaySettings = 2 * Discussions,
    Dropbox = 2 * DisplaySettings,
    Faq = 2 * Dropbox,
    Forms = 2 * Faq,
    Glossary = 2 * Forms,
    Grades = 2 * Glossary,
    GradesSettings = 2 * Grades,
    Groups = 2 * GradesSettings,
    Homepages = 2 * Groups,
    IntelligentAgents = 2 * Homepages,
    Links = 2 * IntelligentAgents,
    LtiLink = 2 * Links,
    LtiTP = 2 * LtiLink,
    Navbars = 2 * LtiTP,
    News = 2 * Navbars,
    QuestionLibrary = 2 * News,
    Quizzes = 2 * QuestionLibrary,
    ReleaseConditions = 2 * Quizzes,
    Rubrics = 2 * ReleaseConditions,
    Schedule = 2 * Rubrics,
    SelfAssessments = 2 * Schedule,
    Surveys = 2 * SelfAssessments,
    ToolNames = 2 * Surveys,
    Widgets = 2 * ToolNames,
}
于 2017-12-09T15:14:03.130 回答
-5
#define BITS  \
    F(Campaigns) \
    F(Quizzes) \
    F(Groups) \
    F(Homepages)

#define F(x) x##_BIT,

enum bits {
    BITS
};

#undef F
#define F(x) x = (1 << x##_BIT),

enum flags {
    BITS
};
于 2019-04-04T05:13:03.197 回答