Когда выполняется конструктор пользовательских атрибутов?
Намерение:
Я пишу бизнес-приложение, которое использует несколько перечислений, где большинство этих перечислений также существует в таблицах базы данных. Проблема заключается в обслуживании, когда один из членов команды или поздний разработчик изменяет значение члена перечисления в одном из двух мест, оставляя перечисление несинхронизированным. Чтобы решить эту проблему, я пытаюсь создать пользовательский атрибут enum, который выдает какое-то исключение, когда обнаруживает, что значения enum не синхронизированы.
Реализация:
[AttributeUsage(AttributeTargets.Enum)]
public class EnumSyncAtrribute : Attribute
{
public EnumSyncAtrribute(Type databaseAccessType, Type enumType))
{
// Code that uses that databaseAccessType to access the database to get
// enum values then compare it to values of enumType , goes here.
}
}
Тогда целевой enum помечается следующим образом
[EnumSyncAtrribute(typeof(MyDataBaseAccess), typeof(MyEnum))]
public enum MyEnum
{
value1 = 0,
value2 = 1,
value3 = 2
}
Проблема:
Проблема в том, что этот конструктор атрибута никогда не выполняется! Я попытался заменить Enums классами и обнаружил, что он работает нормально, а с Enums - нет!
Вопрос в том, когда пользовательские атрибуты используются для перечислений, когда выполняются их конструкторы?
1 ответ
Атрибут создается только при извлечении его (используя GetCustomAttribute
функция). В противном случае его рецепт построения (перегрузка конструктора + позиционные параметры + значения свойств) сохраняется только в метаданных сборки.
В вашем случае я бы забрал все типы перечислений из сборки и проверил, имеют ли они атрибут. Нечто подобное при запуске вашего приложения:
var allEnumTypes = Assembly.GetExecutingAssembly()
.GetTypes()
.Where(t => t.IsEnum);
foreach(var enumType in allEnumTypes)
{
var syncAttr = Attribute.GetCustomAttribute(enumType, typeof(EnumSyncAtrribute)) as EnumSyncAtrribute;
if (syncAttr != null)
{
// Possibly do something here, but the constructor was already executed at this point.
}
}