使用隐式数组初始化程序作为C#属性参数编译错误

时间:2013-07-08 12:39:40

标签: c#

我在以下测试用例中遇到了一个神秘的编译错误:

[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?)使用默认值隐式初始化每个元素,因此不会发生编译错误。

1 个答案:

答案 0 :(得分:0)

在你的第一个构造中,你只是声明了一个259字节的数组,但它没有初始化。当然,CLR会自动初始化内在值(实际上,这是一个数组,所以它甚至不是内在的,它是一个对象 - byte[]关键字(和运算符)只是语法糖,使编写和阅读代码更容易事实上,如果你写了Array<System.Byte> someArray;someArray在你初始化之前就会为空,例如someArray = new Array<System.Byte>(259);

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

声明的数组就是声明。它有什么吗?你没有这么说,但编译器不能假设你想要一个零填充数组。您必须明确告诉它使用什么值。属性在编译时进行评估,adorn / decorate代码构造为您使用它们的各种代码构造提供元数据(或提供的附加功能)。