Это действительно невероятно, но реально. Этот код не будет работать:
[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; }
}
Кто может сказать мне, почему дважды в порядке, в то время как десятичное число не.
Это ограничение среды CLR. Только примитивные константы или массивы примитивы могут использоваться как атрибут параметры. Причина в том, что атрибут должен быть полностью закодирован в метаданные.Это отличается от тело метода, которое закодировано в IL. Использование метаданных только сильно ограничивает диапазон значений, которые можно использовать. В текущей версии CLR значения метаданных ограничены примитивы, null, типы и массивы примитивы (возможно, пропустил второстепенный один).
Взято из этого ответа JaredPar .
Десятичные дроби, если основной тип не является примитивный тип и, следовательно, не может быть представлены в метаданных, что предотвращает он не является параметром атрибута.
Из спецификации:
Типы позиционных и именованных параметров для класса атрибутов ограничены типами параметров атрибута, которые являются:
- Один из следующих типов:
bool
,byte
,char
,double
,float
,int
,long
,sbyte
,short
,string
,uint
,ulong
,ushort
.- Тип
object
.- Тип
System.Type
.- Тип enum, при условии, что он имеет общедоступность и типы, в которые он вложен (если таковые имеются), также имеют общедоступность (спецификация Attribute).
- Одномерные массивы вышеперечисленных типов.