【问题标题】:Why "decimal" is not a valid attribute parameter type?为什么“十进制”不是有效的属性参数类型?
【发布时间】:2011-03-12 16:37:36
【问题描述】:

这真的令人难以置信,但却是真实的。此代码将不起作用:

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

【问题讨论】:

标签: c# .net attributes


【解决方案1】:

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

取自this 回复JaredPar

基本类型不是小数 原始类型,因此不能 以元数据表示,可防止 它不是一个属性参数。

【讨论】:

  • 为什么小数在 CLR 中不被视为原始类型?
  • @koumides 我相信答案是类型太大,无法在单个 CPU 寄存器中表达,因为它是 128 位
  • 好的,为什么允许字符串作为属性属性?我想它属于“基元数组”类别,但它是堆分配的(引用类型)......
  • 因为字符串是引用类型,处理方式完全不同。
  • @Soren 这不是真的,支持Enum。我目前有 2 个自定义属性,一个有 2 个枚举,另一个有一个枚举数组。
【解决方案2】:

来自specs

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

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

【讨论】:

  • 正确,但请注意您引用的是旧版本的规范。在 C# 版本 3.0、4.0 和 5.0 中,声明它还可以具有类型 sbyteushortuintulong。这似乎工作得很好。但仍然不允许decimal :-(
  • @JeppeStigNielsen 我已经更新了规范链接和报价
  • 不支持可空原语。
【解决方案3】:

这个问题的答案是使用字符串,尽管它不是原子类型,但仍允许作为属性。不要使用双精度数,因为四舍五入会降低结果的准确性。

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

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

private decimal minimumValueDecimal;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-10-31
    • 1970-01-01
    • 1970-01-01
    • 2011-10-25
    • 1970-01-01
    • 2020-10-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多