Comments 14
Спасибо! Мне тоже кажется работа с «enum + аттрибуты» часто более удобной.
> Я бы выделил несколько причин, по которым считаю этот подход неудачным:
Я бы добавил к минусам следующее:
С immutable-классами так работать нельзя. Здесь лучше использовать StringBuilder и string.Format("",...).
А в плюсы энумок добавил бы упрощение локализации через аттрибуты. К примеру, можно для значений указать аттрибуты вида «LocalizableFriendlyName» и через extension-methods возвращать для конкретного значения перечисления локализованное дружественное имя и какого-либо ресурса.
> Я бы выделил несколько причин, по которым считаю этот подход неудачным:
Я бы добавил к минусам следующее:
strQuery += "DateFrom >= '" + DateFromValue.ToString() + "'";
С immutable-классами так работать нельзя. Здесь лучше использовать StringBuilder и string.Format("",...).
А в плюсы энумок добавил бы упрощение локализации через аттрибуты. К примеру, можно для значений указать аттрибуты вида «LocalizableFriendlyName» и через extension-methods возвращать для конкретного значения перечисления локализованное дружественное имя и какого-либо ресурса.
Мне кажется, уже есть стандартный для вашего случая формат метаданных — Expressions. И с помощью PredicateBuilder легко получить такие «собираемые предикаты» и потом на этот полученный Expression можно скормит Entity Framework, LINQ, или даже для некоторого несложного подмножества написать свою реализацию репозитория, разбирающего выражение и делая запрос на основе него к произвольному хранилищу.
Лишние переносы строк в примерах кода уберите, пожалуйста.
Справился с оформлением кода. Оказывается хабр умеет сам подсвечивать исходники, однако это не сразу найдешь.
У вас есть конкретный enum DGA, к которому вы добавили конкретные extensions DGAExt. Зачем использовать медленный reflection, когда можно было просто сделать в классе DGAExt
private Dictionary<DGA, string> attributeNames = new Dictionary<DGA, string>
{
{ DGA.RegDate, «doc_RegCard/rc_Index/date_Дата_регистрации» },
{ DGA.RegNum, «doc_RegCard/rc_Index/text_Регистрационный_номер» },
…
};
public static string GetAttribName(this DGA attrib)
{
return this.attributeNames[ attrib ];
}
Либо вообще сделать attributeNames public и обойтись без метода, хотя метод позволяет добавить валидацию в случае необходимости.
Без reflection скорость выше, понятность в худшую сторону не меняется, весь мэппинг аналогично находится в одном месте, просто не в декларации самого enum.
private Dictionary<DGA, string> attributeNames = new Dictionary<DGA, string>
{
{ DGA.RegDate, «doc_RegCard/rc_Index/date_Дата_регистрации» },
{ DGA.RegNum, «doc_RegCard/rc_Index/text_Регистрационный_номер» },
…
};
public static string GetAttribName(this DGA attrib)
{
return this.attributeNames[ attrib ];
}
Либо вообще сделать attributeNames public и обойтись без метода, хотя метод позволяет добавить валидацию в случае необходимости.
Без reflection скорость выше, понятность в худшую сторону не меняется, весь мэппинг аналогично находится в одном месте, просто не в декларации самого enum.
Да, наверное в случае когда нужно привесить одну строку такой вариант можно использовать.
Разница, наверное, не столько в читаемости, сколько в гарантии неизменности словаря.
Хотя был случай, когда я как раз такой словарь и использовал, а наполнялся он в процессе работы программы.
Насчет производительности ничего не могу сказать, но я не думаю, что конкретно в этом случае reflection сильно медленнее словаря, надо будет померять при случае.
Разница, наверное, не столько в читаемости, сколько в гарантии неизменности словаря.
Хотя был случай, когда я как раз такой словарь и использовал, а наполнялся он в процессе работы программы.
Насчет производительности ничего не могу сказать, но я не думаю, что конкретно в этом случае reflection сильно медленнее словаря, надо будет померять при случае.
Почему «привесить одну строку»? Как ваш атрибут можно расширять свойствами, так и мэппинг можно делать не в строку, а в сложный класс, имеющий все небходимые свойства, либо делать набор мэппингов — по вкусу.
Что касается неизменяемости словаря, что вас смущает, если он скрыт, а доступ организован через метод?
Что касается неизменяемости словаря, что вас смущает, если он скрыт, а доступ организован через метод?
*Долго думал
Давайте чуть-чуть проанализируем.
Чем плохо использование атрибутов по сравнению со словарем?
Судя по всему — только производительностью
Чем плохо использование словаря по сравнению с атрибутами?
На этот вопрос я долго не мог ответить даже для себя. Было только подсознательное ощущение какой-то неправильности. Наконец осознал. Проблема чисто организационная — информация о присоединенных атрибутах находится в стороне от объявления элементов перечисления. Таким образом,если когда кто-то будет добавлять элементы перечисления, то он может не сходу увидеть, что атрибуты добавляются где-то еще. Т.е. имеет место небольшое нарушение принципа DRY: каждый элемент перечисления нужно продублировать в инициализаторе словаря.
Вариант решения
В итоге мне кажется разумным использовать комбинированный вариант, а именно, писать метаданные в атрибуты, но завести словарь, информация в который загружается в процессе выполнения(например, в статическом конструкторе класса-расширения). Это обеспечит нужную производительность и сохранит прозрачность кода.
Давайте чуть-чуть проанализируем.
Чем плохо использование атрибутов по сравнению со словарем?
Судя по всему — только производительностью
Чем плохо использование словаря по сравнению с атрибутами?
На этот вопрос я долго не мог ответить даже для себя. Было только подсознательное ощущение какой-то неправильности. Наконец осознал. Проблема чисто организационная — информация о присоединенных атрибутах находится в стороне от объявления элементов перечисления. Таким образом,
Вариант решения
В итоге мне кажется разумным использовать комбинированный вариант, а именно, писать метаданные в атрибуты, но завести словарь, информация в который загружается в процессе выполнения(например, в статическом конструкторе класса-расширения). Это обеспечит нужную производительность и сохранит прозрачность кода.
Sign up to leave a comment.
Представление метаданных с помощью перечислений