这真的令人难以置信,但真实。此代码无效:
[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是可以的,而decimal不是。
答案 0 :(得分:121)
这是CLR限制。只要 原始常量或数组 基元可以用作属性 参数。原因是一个 属性必须完全编码 元数据。这与a不同 用IL编码的方法体。 使用MetaData只会严格限制 可以使用的值的范围。 在当前版本的CLR中, 元数据值仅限于 原语,null,类型和数组 原始人(可能错过了一个未成年人 一个)。
基本类型不是的小数 原始类型因此不可能 在元数据中表示阻止 它来自属性参数。
答案 1 :(得分:49)
来自specs:
属性类的位置和命名参数的类型 仅限于属性参数类型,它们是:
- 以下类型之一:
bool
,byte
,char
,double
,float
,int
,long
,sbyte
,short
,string
,uint
,ulong
,ushort
。- 类型
object
。- 类型
System.Type
。- 枚举类型,前提是它具有公共可访问性,并且嵌套类型(如果有)也具有公共可访问性(属性规范)。
- 上述类型的一维数组。
答案 2 :(得分:1)
这个问题的答案是使用字符串,尽管它不是原子类型,但它们被允许作为属性。不要使用双打,因为舍入会使结果不准确。
public String MinimumValue
{
get
{
return minimumValueDecimal.ToString();
}
set
{
minimumValueDecimal = Decimal.Parse(value);
}
}
private decimal minimumValueDecimal;