Подтвердить что ты не робот

Являются ли особые атрибуты для Enums опасными?

Я создаю приложение, которое сильно использует Enum для пользовательских данных. По существу, объект хранится в базе данных с примерно 28 отдельными атрибутами. Каждый атрибут представляет собой двухсимвольное поле, которое переводится с SQL прямо на Enum.

К сожалению, мне нужно также перевести эти значения в два разных для человека значения. Один для легенды в таблице данных и один для класса CSS для стилизации изображения в интерфейсе веб-приложения.

Для этого я настроил два настраиваемых атрибута и применил их к Enum там, где это необходимо. Например:

Пользовательский интерфейс атрибутов

public interface IAttribute<T>
{
    T Value { get; }
}

Пример пользовательского атрибута

public sealed class AbbreviationAttribute: Attribute, IAttribute<string>
{
    private readonly string value;

    public AbbreviationAttribute(string value)
    {
        this.value = value;
    }

    public string Value
    {
        get { return this.value; }
    }
}

Метод получения пользовательского атрибута из Enum

public static R GetAttributeValue<T, R>(IConvertible @enum)
{
    R attributeValue = default(R);

    if (@enum != null)
    {
        FieldInfo fi = @enum.GetType().GetField(@enum.ToString());

        if (fi != null)
        {
            T[] attributes = fi.GetCustomAttributes(typeof(T), false) as T[];

            if (attributes != null && attributes.Length > 0)
            {
                IAttribute<R> attribute = attributes[0] as IAttribute<R>;

                if (attribute != null)
                {
                    attributeValue = attribute.Value;
                }
            }
        }
    }

    return attributeValue;
}

Пример Enum Использование этого шаблона

public enum Download
{
    [Abbreviation("check")]
    [Description("Certified")]
    C = 1,

    [Abbreviation("no-formal")]
    [Description("No formal certification")]
    NF = 2,

    [Abbreviation("cert-prob")]
    [Description("Certified with potential problems")]
    CP = 3
}

Оба Abbreviation и Description являются пользовательскими атрибутами, реализующими IAttribute<T>. Мой фактический Enum имеет 11 возможных значений, и, как я уже упоминал ранее, он используется в 28 отдельных свойствах в моем пользовательском объекте. Использование пользовательских атрибутов казалось лучшим способом сопоставить эту информацию взад и вперед.

Теперь для вопроса, это лучший способ добиться этого? Я храню значение Enum ( "C", "NF" или "CP" в фрагменте выше) в базе данных, но мне нужны значения аббревиатуры и описания в моем коде. Кроме того, я сомневаюсь, что это будет окончательный набор настраиваемых атрибутов, которые мне понадобятся.

Прежде чем я продолжу двигаться вперед с этим шаблоном... это правильный способ сделать что-то? Я предпочел бы исправить потенциальные проблемы с этим подходом сейчас, чем отследить назад и реорганизовать позже.

4b9b3361

Ответ 1

Это тот же метод, который я использую. Единственным недостатком является сериализация. Значения пользовательских атрибутов не сериализуются.

Мне нравится метод настраиваемых атрибутов по методу базы данных, потому что он связывает данные атрибута с enum вместо использования таблицы или класса поиска и т.д.

Ответ 2

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

class SpecialType {
  // include the fields and all attributes that you need to reference, ToString method for debugging, and any serialization you need
  public string foo { get; set; }
  public string bar { get; set; }
  public ToString() { return "SpecialType with foo '" + foo + "' and bar '" + bar + "'"; }
}

Dictionary<int, SpecialType> myDict = new Dictionary<int, SpecialType> {
   { 1, new SpecialType { foo = "XA1B2", bar = "XC3D4" } },
   { 2, new SpecialType { foo = "ZA1B2", bar = "ZC3D4" } },
   { 3, new SpecialType { foo = "YA1B2", bar = "YC3D4" } },
}

Тогда я мог бы легко сохранить ints в моих других классах, чтобы сохранить память, выяснить, действительно ли определенное значение было проверено на наличие в ключах словаря, все это джаз. Скорее всего, было бы намного проще выполнить привязку данных, если в конечном итоге вы будете использовать WPF или читать/записывать на диск.

Ответ 3

Вы можете изменить базу данных? Я думаю, что лучшим вариантом было бы сделать таблицу (или таблицы) для размещения возможных значений переписей и внешнего ключа основными объектами (вместо использования кодов char), это упрощает и упрощает БД). Дайте таблице столбец Abbreviation и Description, затем потяните их и скопируйте их по их ключу и кешируйте их, если поисковые запросы будут медленными.

Одна вещь, которая опасна для атрибутов, заключается в том, что если какая-либо из этих строк когда-либо должна измениться, это полное перераспределение приложения. Если вы сделаете их значения базы данных, вы можете изменить их с помощью простого UPDATE.