Могу ли я иметь атрибут внутри атрибута?
Я работаю над приложением, которое будет считывать данные из моей базы данных, выполнять некоторую обработку, а затем экспортировать результаты в плоский файл фиксированной ширины.
Я начинаю с кода в этом вопросе и строю его.
Теперь существует три основных типа данных для экспортируемого файла: String, Num и Decimal(x,y); где x - числа слева от десятичной точки, а y - числа справа.
У меня есть это, насколько мой собственный атрибут:
public class FixedWidthColumn : Attribute
{
public int Position { get; set; }
public int Length { get; set; }
public FixedWidthColumn(int position, int length)
{
Position = position;
Length = length;
}
}
Можно ли создать пользовательский атрибут (или некоторую другую структуру), который я могу использовать для создания свойств, как это:
[FixedWidthColumn(3,2, String)]
public string CompanyId
[FixedWidthColumn(6, 20, Num)]
public int Sku { get; set; }
[FixedWidthColumn(5, 10, Decimal(6,4)]
public decimal Price { get; set; }
4 ответа
Вы можете расширить FixedWidthColumnAttribute для переноса свойства типа параметра.
public enum FixedWidthColumnType
{
String,
Num,
Decimal
}
[AttributeUsage(AttributeTargets.Property)]
public class FixedWidthColumnAttribute : Attribute
{
public int Position { get; private set; }
public int Length { get; private set; }
public int Digits {get;set;}
public int FractionalDigits {get;set}
public FixedWidthColumnType Type {get; private set;}
public FixedWidthColumn(int position, int length,
FixedWidthColumnType type)
{ this.Position = position;
this.Length = length;
this.Type = type;
}
}
использование:
[FixedWidthColumn(4, 10, FixedWidthColumnType.String)]
[FixedWidthColumn(5, 6, FixedWidthColumnType.Decimal, Digits = 3, FractionalDigits = 4)]
Во-первых, вы должны переименовать имя вашего класса FixedWithColumn в FixedWithColumnAttribute. Может быть, это просто соглашение; но я думаю, что это необходимо для применения с семантикой C#. Во-вторых, вы должны указать typeof(Type) в объявлении атрибута вызова:
[FixedWidthColumn(3,2,typeof(String))]
В-третьих, объявите конструктор так:
public FixedWidthColumnAttribute(int position, int length, Type objType)
Я надеюсь, что это может помочь вам
Чтобы ответить на конкретный вопрос: нет, вы не можете иметь атрибут в атрибуте.
Атрибуты могут принимать только ограниченный диапазон типов данных в своих конструкторах. См. Документацию MSDN для примеров. Таким образом, вы не можете иметь атрибут, который представляет класс как свойство.
Я бы порекомендовал использовать наследование, например:
public class FixedWidthDecimalAttribute : FixedWidthColumnAttribute
...
public FixedWidthDecimal(int position, int wholeDigits, int fractionalDigits)
...
[FixedWidthDecimal(5, 6, 4)]
В коде экзамена вы можете получить все FixedWidthColumnAttribute
объекты, разрешающие наследование, затем исследуют тип (используя GetType
) точно определить, что это за объект.