Почему "десятичный" не является допустимым типом параметра атрибута?
Это действительно невероятно, но реально. Этот код не будет работать:
[AttributeUsage(AttributeTargets.Property|AttributeTargets.Field)]
public class Range : Attribute
{
public decimal Max { get; set; }
public decimal Min { get; set; }
}
public class Item
{
[Range(Min=0m,Max=1000m)] //compile error:'Min' is not a valid named attribute argument because it is not a valid attribute parameter type
public decimal Total { get; set; }
}
Пока это работает:
[AttributeUsage(AttributeTargets.Property|AttributeTargets.Field)]
public class Range : Attribute
{
public double Max { get; set; }
public double Min { get; set; }
}
public class Item
{
[Range(Min=0d,Max=1000d)]
public decimal Total { get; set; }
}
Кто может сказать мне, почему double - ОК, а десятичное - нет.
Ответы
Ответ 1
Это ограничение CLR. Только примитивные константы или массивы примитивы могут использоваться как атрибут параметры. Причина в том, что атрибут должен быть полностью закодирован в метаданные. Это отличается от который закодирован в IL. Использование MetaData строго ограничивает объем значений, которые можно использовать. В текущей версии CLR, значения метаданных ограничены примитивы, нули, типы и массивы примитивы (возможно, пропустили минор один).
Взято из этого ответа JaredPar.
Десятичные числа, в то время как базовый тип не является примитивный тип и, следовательно, не может быть представленный в метаданных, который предотвращает это параметр атрибута.
Ответ 2
Из спецификации:
Типы позиционных и именованных параметров для класса атрибутов ограничены типами атрибутных параметров, которые:
- Один из следующих типов:
bool
, byte
, char
, double
, float
, int
, long
, sbyte
, short
, string
, uint
, ulong
, ushort
. - Тип
object
. - Тип
System.Type
. - Тип перечисления при условии, что он имеет общедоступную доступность, а типы, в которых он вложен (если есть), также имеют общедоступную доступность (спецификация атрибута).
- Одномерные массивы вышеуказанных типов.