Альтернатива наследования перечислений .NET


Я хотел бы создать перечисление для ACCESS_MASK я должен использовать с P / Invoke , но я не знаю, что было бы лучшим способом для такой реализации.

1. Если бы это было возможно:

[Flags]
enum ACCESS_MASK : uint
{
    STANDARD_RIGHTS_REQUIRED = 0x000F0000,
    SYNCHRONIZE = 0x00100000,
    // Everything reused in the specific rights ...
}

[Flags]
enum PROCESS_ACCESS_MASK : ACCESS_MASK
{
    // ...
    PROCESS_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFFF,
}

2. Все в одном лице: (автоматическое представление строк невозможно)

[Flags]
enum ACCESS_MASK : uint
{
    STANDARD_RIGHTS_REQUIRED = 0x000F0000,
    SYNCHRONIZE = 0x00100000,
    // ...
    PROCESS_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFFF,
}

3. Разделить и переписать: (Muuuuch дубликат кода)

[Flags]
enum PROCESS_ACCESS_MASK : uint
{
    STANDARD_RIGHTS_REQUIRED = 0x000F0000,
    SYNCHRONIZE = 0x00100000,
    // ...
    PROCESS_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFFF,
}

4. Разделить и взять из основного: (конкретное перечисление ничего не знает о самих базовых значениях)

[Flags]
enum ACCESS_MASK : uint
{
    STANDARD_RIGHTS_REQUIRED = 0x000F0000,
    SYNCHRONIZE = 0x00100000,
    // Everything reused in the specific rights ...
}

[Flags]
enum PROCESS_ACCESS_MASK : uint
{
    // ...
    PROCESS_ALL_ACCESS = ACCESS_MASK.STANDARD_RIGHTS_REQUIRED | ACCESS_MASK.SYNCHRONIZE | 0xFFFF,
}

Какой вариант вы предпочитаете, или есть ли лучшие способы для реализации ACCESS_MASK?

кстати: что такое доступ к файлам 0x100001?

Edit: я знаю, что нет никакого перечислительного наследования и ACCESS_MASK : uint ничего подобного, но воображаемое PROCESS_ACCESS_MASK : ACCESS_MASK было бы.

2 2

2 ответа:

Предполагая, что вы скрываете детали P/Invoke от остальной части приложения, и что значения ACCESS_MASK используются только очень локально, я бы просто поместил все опции в одно перечисление - ваш вариант 2.

Кроме того, я бы отметил перечисление с помощью FlagsAttribute чтобы указать, что он рассматривается как битовое поле.

Что вы можете сделать:

public enum ACCESS_MASK : uint
{
    STANDARD_RIGHTS_REQUIRED = 0x000F0000,
    SYNCHRONIZE = 0x00100000,
    // Everything reused in the specific rights ...
}

public static class Masks
{
    // ...
    public const ACCESS_MASK PROCESS_ALL_ACCESS = ACCESS_MASK.STANDARD_RIGHTS_REQUIRED | ACCESS_MASK.SYNCHRONIZE | (ACCESS_MASK) 0xFFFF;
}

Таким образом, вы сохраняете перечисление в предпочтительной форме. Это было вдохновлено на то, как Winforms определяет класс Color с определенными Colors в отдельном статическом классе.