在C#中使用十进制值作为属性参数?


Answers:


121

这是CLR限制。仅原始常量或原始数组可以用作属性参数。原因是属性必须完全在元数据中编码。这与用IL编码的方法主体不同。仅使用MetaData会严格限制可以使用的值的范围。在CLR的当前版本中,元数据值限于原语,空值,原语的类型和数组(可能遗漏了较小的一个)。

基本类型不是原始类型的小数,因此不能在元数据中表示,这阻止了它成为属性参数。


5
这仍然是Framework 4.0的问题吗?和4.5、4.6.x?
2016年

@midspace并不是设计带来的问题,只是一个限制。这很不幸,但是很有可能永远不会消失。
Bruno Brant

1
“只有原始常量或原始数组可以用作属性参数。” 似乎并非完全正确,例如,还允许使用System.Type:msdn.microsoft.com/en-us/library/aa664615
v=vs.71).aspx

Using MetaData only severely restricts the scope of values that can be used-为什么呢?元数据可用于指向类型定义。例如,当您在常规类中定义字段时,将发出元数据,其中包括字段名称及其类型(任何类型,而不是突出原语)。我不明白为什么不能将此用于属性。
温格·森顿

15

我也有同样的问题。我考虑使用字符串。这不是类型安全的,但是它是可读的,我认为我们将能够在字符串中写入有效数字:-)。

class BlahAttribute : Attribute
{
  private decimal value;

  BlahAttribute(string number)
  {
    value = decimal.Parse(number, CultureInfo.InvariantCulture);
  }
}

[Blah("10.23")]
class Foo {}

这不是美,但考虑所有选择之后,就足够了。


1
像这看起来是如何MbUnit的COPES vkreynin.wordpress.com/2007/05/25/...
安迪·登特

2

当遇到这种情况时,我最终将属性作为Double公开,但是在属性内部将它们视为Decimal。远非完美,但对于简单的情况,可能正是您所需要的。



0

您可以使用以下构造函数。当您在C#代码中使用十进制文字时,C#编译器将对此构造函数进行调用。

Decimal(Int32, Int32, Int32, Boolean, Byte)

编辑:我知道这不方便。


2
如果这在属性中起作用,那么我猜想也可以简单地使用“ m”后缀,但是两者都不起作用(使用System.ComponentModel.DefaultValueAttribute作为我的测试)
xr280xr 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.