Являются ли особые атрибуты для 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" в фрагменте выше) в базе данных, но мне нужны значения аббревиатуры и описания в моем коде. Кроме того, я сомневаюсь, что это будет окончательный набор настраиваемых атрибутов, которые мне понадобятся.
Прежде чем я продолжу двигаться вперед с этим шаблоном... это правильный способ сделать что-то? Я предпочел бы исправить потенциальные проблемы с этим подходом сейчас, чем отследить назад и реорганизовать позже.
Ответы
Ответ 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
.