2013-07-08 79 views
4

我有与下面的测试情况下,一个神秘的编译错误:编译错误属性参数

[TestCase(new byte[259], new byte[] { 0, 0, 0, 0, 255 })] 
public void EncodeTest(byte[] source, byte[] expected) { 
    ... 
} 

error CS0182: An attribute argument must be a constant expression, 
typeof expression or array creation expression of an attribute parameter type 

如果我更换属性的第一个参数如下:

[TestCase(new byte[259] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
          0, 0, 0 }, 
       new byte[] { 0, 0, 0, 0, 255 })] 
public void EncodeTest(byte[] source, byte[] expected) { 
    ... 
} 

它编译得很好。为什么?

更新:让我澄清这个问题。如果你写类似下面的代码:因为编译器发生

int[] arr = new int[259]; 
Console.Write(arr[0]); // 0 

没有编译错误隐含初始化与默认值的每一个元素(或CLR?)。

+0

访问http://stackoverflow.com/questions/10445663/c-what-is-a-constant-expression – Satpal

+0

你应该专注于一个属性的实际用法,该属性需要一个未初始化的数组。没有意义,你可以在属性构造函数中创建该数组。 –

+0

@HansPassant看起来这个属性可能是NUnit相关的,不在OP的控制之下。即使不是这样,我认为仍然值得质疑为什么两种表达方式之间存在差异,而这些表达方式(通过我的阅读)声称应该是相同的。 – shambulator

回答

0

在你的第一个构造中,你只需声明一个259字节的数组,但它是未初始化的。当然,CLR会自动初始化内部值(实际上,这是一个数组,因此它甚至不是内在的,它是一个对象 - 关键字(和运算符)仅仅是语法糖,使得编写和读取代码更容易。事实上,如果你写Array<System.Byte> someArray;,直到你初始化它someArray将是空,如someArray = new Array<System.Byte>(259);

属性,为错误状态,需要(可以恒定或东西)常数作为参数。

一声明的数组就是这样一个声明,它里面有什么吗?你没有这么说,但编译器不能假设你想要一个零填充的数组,你必须明确地告诉它使用什么值。在c ompile-time和adorn/decorate构造提供了元数据(或附加功能提供)给你用过的各种代码构造。

+2

int [] arr = new int [259];'隐式地初始化每一个默认的int值为0的元素。不需要追加'{0,0,0,...,0}'。我仍然不明白他们为什么不同。 –

+1

@fourpastmidnight这个错误实际上明确指出,常量表达式只是一种允许的属性参数,另一种是“属性参数类型的数组创建表达式”。从规范的角度来看,问题中使用的两个表达式似乎没有区别;正如OP所说,短格式将每个元素的默认值初始化。 – shambulator

+0

是的,你没事。不应该有区别。好决定。事实上,我错过了OP中的'new'关键字,无论如何,如果它被遗忘了,它将会是一个不同的编译时错误。 – fourpastmidnight