2015-09-29 3 views
0

Я хочу, чтобы иметь возможность сопоставлять каждое значение Enum с другим class (и наоборот), но сохраняйте отношения в одном месте, чтобы они могли быть изменены/добавлены без внесения изменений в нескольких местах.Отображение значений перечисления классам

Какой шаблон позволит мне отображать значения Enum для классов?

Мое конкретное использование примерно следующим образом:

У меня есть Person класса, который содержит общую информацию о человеке. К этому классу могут быть добавлены компоненты (хранящиеся в ListDictionary), которые содержат информацию, относящуюся к конкретному типу человека, например. componentCustomer, componentEndUser, componentSupplier. Эти компонентные классы реализуют интерфейс IPersonComponent. Важно отметить, что человек может быть более одного типа и поэтому может содержать более одного компонента.

У меня также есть Enum ePersonType со значениями, например. Клиент, Конечный пользователь, Поставщик. Каждое значение имеет отношение «один к одному» с компонентом.

Когда запись человека извлекается, значение List<int> заполняется соответствующими значениями «ePersonType». Этот список затем используется для определения того, какие компоненты должны быть выделены для Person и загружены данными.

Понятно, что это удобно для switch по типам лиц и соответствующим образом добавлять компоненты. Однако, что, если я позже захочу проверить, какие компоненты хранятся в экземпляре человека и что такое ePersonType? Я мог бы switch вернуться на component.GetType(), но тогда я сохраняю отношения в двух местах.

В качестве альтернативы я мог бы хранить соответствующий ePersonType внутри каждого компонента и использовать Linq для проверки того, имеет ли экземпляр человека определенный компонент, но тогда кажется, что исходное распределение было бы более сложным, возможно, требующим отражения?

Я уверен, что у меня отсутствует что-то действительно очевидное здесь.

+0

словари могут быть хорошими здесь? –

+0

Я думаю, вам нужно изменить свой код с помощью перечислений на полиморфизм https://lostechies.com/johnteague/2013/03/03/polymorphism-part-2-refactoring-to-polymorphic-behavior/ – Backs

+0

Я вижу, как использовать словарь для сопоставления каждого значения Enum с _instance_ классов, но я не уверен, как это сделать с самим классом? – Jack

ответ

1

Один из способов я приближался это использовать атрибут на фактических значениях:

public enum PersonType 
{ 
    [PersonClass(typeof(Customer)] 
    Customer, 

    [PersonClass(typeof(EndUser)] 
    EndUser, 

    [PersonClass(typeof(Supplier)] 
    Supplier, 
} 

public class PersonClassAttribute : System.Attribute 
{ 
    public Type Type { get; } 

    public PersonClassAttribute(Type type) 
    { 
     Type = type; 
    } 
} 

Затем используйте статический класс для управления поиском и отображением перечислений типов:

public static class People 
{ 
    static Dictionary<PersonType, Type> mapping = new Dictionary<PersonType, Type>(); 

    static People() 
    { 
     var fields = Enum.GetNames(typeof(PersonType)).Select(n => typeof(PersonType).GetFieldr(n)); 
     mapping = fields.ToDictionary(
      f => (PersonType)f.GetRawConstantValue(), 
      f => f.GetCustomAttribute<PersonClassAttribute>().Type 
      ); 
    } 


    public static T GetPersonInstance<T>(this PersonType type) 
    { 
     return (T)Activator.CreateInstance(mapping[type]); 
    } 
} 

Очевидно, что было бы немного больше (проверка, проверка ошибок и т. Д.), Но это общая идея.

Смежные вопросы