Пользовательский тип Enum - PullRequest
0 голосов
/ 09 июня 2011

У меня есть перечисление, основанное на флаге, и хотя оно в настоящее время не превышает границ значения 64 (long), оно потенциально будет.

Я использую enum, чтобы описать, для какого из наших клиентов предназначен плагин / компонент MEF. Это будет наш основной механизм для реализации пользовательских настроек.

Я вполне уверен, что мои начальники не будут слишком довольны идеей, что мы можем обслуживать только 64 клиента, но я не могу внедрить такую ​​гибкую систему без Enum.

В идеале я хотел бы написать:

[Flags]
public enum Organisations : MyBinaryFormat
{
    // Customers
    CustomerA = 1 << 0,
    CustomerB = 1 << 1,
    CustomerC = 1 << 2,
    CustomerD = 1 << 3,

    // Special
    Any                 = CustomerA | CustomerB | CustomerC,
    HostedCustomers     = CustomerA | CustomerC,
}

Это очень удобный синтаксис для определения моих метаданных, к сожалению, типы взлома на самом деле не моя сильная сторона, поэтому я старался изо всех сил исследовать / экспериментировать по этой теме, но многого не достиг:

  • В этом вопросе говорится, что можно использовать класс BitArray с перечислением, что было бы идеально, однако реализация не предусмотрена.

  • Я видел TypeDef, используемый в документации VS2008, переданной в перечисление здесь . В этом примере он просто маскирует тип bool и выглядит так, как будто это ключевое слово было удалено.

  • Я искал несколько msdn "enum" страниц (я не хотел бы говорить «все», но я видел слишком много для моего же блага). Однако эта страница говорит, что следует рассмотреть возможность использования System.Int32 в качестве типа данных, если перечисление не является перечислением flags, и у вас более 32 флагов.

  • Однако , я получаю исключение: «Ошибка 1: введите байт, sbyte, short, ushort, int, uint, long или ulong Ожидаемый» всякий раз, когда я пытаюсь использовать пользовательский тип. Я не видел ничего (кроме моего исключения), в котором прямо сказано, что вы не можете использовать свой собственный тип данных, но я также не нашел ни одной его реализации.

Я бы хотел знать окончательно, возможно ли создание перечисления для пользовательского типа

Ответы [ 2 ]

3 голосов
/ 09 июня 2011

Что не так с определением класса CustomerList, который содержит список идентификаторов клиентов или даже просто List<int>? .NET API имеет множество методов манипулирования списками, которые позволят вам ИЛИ собирать списки идентификаторов клиентов так же, как вы делали это с помощью перечисления flags.

, например

List<int> hostedCustomers = new List<int>{1,4, 5};
List<int> newCustomers = new List<int>{6,4,7};
List<int> newHostedCustomers = hostedCustomers.Union(newCustomers).ToList();
1 голос
/ 09 июня 2011

Не лучше ли выразить их как массив уникальных строк (или чисел), представляющих идентификатор клиента?

Например, вы можете определить интерфейс метаданных, например:

public interface ICustomerValidityMetadata
{
    string[] ValidCustomers { get; }
}

Который вы могли бы свернуть в атрибут метаданных:

[MetadataAttribute]
public class ExportForCustomerAttribute : ExportAttribute, ICustomerValidityMetadata
{
    public ExportForCustomerAttribute(Type type, params string[] customerIds)
        : base(type)
    {
        ValidCustomers = customerIds ?? new string[0];
    }
}

Который вы могли бы затем применить как:

[ExportForCustomer(typeof(IModule), "CustomerA", "CustomerB")]
public class SomeModule : IModule { }

И затем вы можете фильтровать:

var modules = container.GetExports<IModule, ICustomerValidityMetadata>()
    .Where(l => l.Metadata.ValidCustomers.Contains("CustomerA");

Но, если честно, жесткое кодирование представлений изменяемых объектов - плохая идея, вам действительно нужно динамически выполнять поиск, либо из базы данных, либо из конфигурации, и т. Д. Таким образом, вам нужно только экспортировать некоторые метаданные, представляющие идентификатор модуля, которыйзатем вы можете найти конкретного клиента, чтобы выяснить, можно ли его использовать.

Надеюсь, это поможет.

...