为什么“十进制”不是有效的属性参数类型?

时间:2010-07-07 07:53:37

标签: c# .net attributes

这真的令人难以置信,但真实。此代码无效:

[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不是。

3 个答案:

答案 0 :(得分:121)

  

这是CLR限制。只要   原始常量或数组   基元可以用作属性   参数。原因是一个   属性必须完全编码   元数据。这与a不同   用IL编码的方法体。   使用MetaData只会严格限制   可以使用的值的范围。   在当前版本的CLR中,   元数据值仅限于   原语,null,类型和数组   原始人(可能错过了一个未成年人   一个)。

取自thisJaredPar回答。

  

基本类型不是的小数   原始类型因此不可能   在元数据中表示阻止   它来自属性参数。

答案 1 :(得分:49)

来自specs

  

属性类的位置和命名参数的类型   仅限于属性参数类型,它们是:

     
      
  • 以下类型之一:boolbytechardoublefloatintlongsbyteshortstringuintulongushort
  •   
  • 类型object
  •   
  • 类型System.Type
  •   
  • 枚举类型,前提是它具有公共可访问性,并且嵌套类型(如果有)也具有公共可访问性(属性规范)。
  •   
  • 上述类型的一维数组。
  •   

答案 2 :(得分:1)

这个问题的答案是使用字符串,尽管它不是原子类型,但它们被允许作为属性。不要使用双打,因为舍入会使结果不准确。

public String MinimumValue
{
    get
    {
        return minimumValueDecimal.ToString();
    }

    set
    {
        minimumValueDecimal = Decimal.Parse(value);
    }
}

private decimal minimumValueDecimal;