2012-05-11 18 views
42

Tôi biết tôi có thể nhân nhưng là lập trình lười biếng mà tôi không muốn.Bất kỳ thủ thuật nào để xác định một enum là cờ/quyền hạn của 2 mà không cần một máy tính?

Có ai nghĩ ra một số phép thuật để tự động đánh số enums thành lũy thừa của hai không?

Dưới đây là ví dụ tôi có chỉ để làm cho nó cụ thể:

[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 
} 
+3

Multiply giá trị trước bằng 2? –

+5

điều dễ nhất là ghi nhớ chúng lên đến 2^64? – JeremyWeir

+4

Đó là những tính toán dành cho. Bạn nên sử dụng giá trị hex chỉ để ở lại thực hành với nhân cơ sở 16. :) – IAbstract

Trả lời

90

Viết các giá trị như chuyển bit và cho phép trình biên dịch làm toán: đề nghị

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

James là một tốt nhất, quá. Trong thực tế, tôi thích cách này tốt hơn. Bạn cũng có thể viết nó như thế này:

[Flags] 
private enum Targets : uint 
{ 
    None    = 0, 
    Campaigns   = 1 << 0, 
    CampaignGroups  = 1 << 1, 
    Advertisers   = 1 << 2, 
    AdvertiserGroups = 1 << 3, 
    AffiliateGroups  = 1 << 4, 
    // etc. 
} 
+16

Tôi làm một cái gì đó tương tự ngoại trừ thay vì 2, tôi sử dụng 1 << 1, 1 << 2, 1 << 3, v.v. –

+2

Vì kiểu cơ bản của enum của bạn là 'uint', nó thực sự là' 1u << 0' , '1u << 1' vv Điều đó có thể quan trọng khi bạn đến' LastFlag = 1u << 31'. –

+0

'1 << n' là viết tắt của ** bit n **. Như trong, nếu tôi muốn đặt bit 2, 3 và 6 của một số, tôi sẽ đặt số thành '(1 << 2) | (1 << 3) | (1 << 6) '. Số bạn thay đổi có tương quan trực tiếp với số bit bạn đang vận hành. – indiv

36

Sử dụng ký hiệu thập lục phân là một chút đơn giản hơn ký hiệu thập phân cũng (không tính bắt buộc):

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

Không khá thanh lịch như các giải pháp Cody và James' , nhưng không yêu cầu máy tính.

+1

Tôi đã thấy hệ thống này được sử dụng rộng rãi nhiều lần. vì vậy bạn nên biết khi bạn gặp phải mã sử dụng nó. Tôi sử dụng '1 <<' cá nhân –

1

Tua nhanh năm năm tới trong tương lai và bắt đầu bằng C# 7.0, bạn có thể sử dụng chữ số nhị phân mới để đơn giản hóa khai báo cờ enum.

[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

+0

Tất nhiên toàn bộ điều có thể được tự động bằng cách giới thiệu một sự quá tải mới cho lớp thuộc tính Flags có một bool "Auto". Vì vậy, [Flags (true)] sau đó có thể phục vụ để có enum tự động dân cư bằng cách liên tục trái bit chuyển từng thành viên. – Hugh

1

Dưới đây là thêm một cách tiếp cận khác:

[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, 
} 
Các vấn đề liên quan