2013-04-08 73 views
2

为什么下面的代码给我例外C#编译器错误:引起通过传递默认字符串参数属性

CSC错误CS0182:属性参数必须是常量表达式的typeof的表达或数组创建表达式属性参数类型

在我的构建服务器上?

/// Customer.cs... 

[Search(SearchAttribute.SearchDisplay.Regular)] 
public Category Category 
{ 
    get; set; 
} 

public enum Category : byte 
{ 
    X = 0x01, 
    Y = 0x02, 
    ... 
} 

/// SearchAttribute.cs... 

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)] 
public class SearchAttribute : Attribute 
{ 
    public SearchDisplay Display { get; private set; } 

    public enum SearchDisplay 
    { 
     None = (byte) 0x01, 
     Regular = (byte) 0x02 
    } 

    public SearchAttribute(SearchDisplay display, string columnName = null) 
     : base() 
    { 
     Display = display; 
    } 
} 

非常感谢。

令人难以置信的是,它在VS2012中建造得很好。我不确定编译器在服务器上运行的版本是什么 - 但我确信它不是2012版本。

UPDATE

多亏了下面的回答者我已经想通了这一点:

我使用VS2012,但定制服务器仍在使用Visual Studio 2010的构建过程。在属性中使用空值默认参数时会出现a bug in the VS2010/C#4 compiler。我可以解决这个3种方式:

  1. 不要使用默认参数 - public SearchAttribute(SearchDisplay display, string columnName)
  2. 使用空字符串 - 公共SearchAttribute(SearchDisplay显示,字符串COLUMNNAME = “”)
  3. 更新我的构建服务器。

我刚刚和2一起去。 3是我以后需要考虑的事情。

+1

请参阅以下相关主题:http://stackoverflow.com/questions/8290853/attribute-argument-must-be-a-constant-error-when-using-an-optional-parameter-in http:// stackoverflow .com/questions/3436848/default-value-for-attribute-constructor http://stackoverflow.com/questions/8189807/attributes-and-named-optional-constructor-parameters-not-working http://stackoverflow.com/questions/15048847/attribute-argument-must-be-a-constant-expression显然这是一个现在已经解决的错误。适用于VS2010。必须安装一些您的构建服务器没有的修补程序。 – 2013-04-08 17:01:45

回答

3

我觉得Customer.cs文件是在一个单独的组件(C#项目),以及装配引用在其中SearchAttribute.cs所在的组件(项目)。

对于枚举SearchDisplay并在构造函数的可选参数columnName正常工作,它是那么至关重要的是两个组件以正确的顺序重新编译。我怀疑你的构建服务器不是这种情况。依赖程序集可能是编译时引用了SearchAttribute所在的程序集的旧版本。

UPDATE

查看所有右边的链接线。这是一个他们认为用Visual Studio 2012(C#5编译器)修复的bug。只有当可选参数的默认值是null时才会发生。在我的第一个测试中,我做出了使用另一个字符串(这将被识别)的愚蠢决定,但它不会发生在另一个字符串中。 (将在下面清除我的评论。)

当属性的用法是在同一个组件设置为属性类本身,它有助于给null字面一个明确的类型,如:

public SearchAttribute(SearchDisplay display, string columnName = (string)null) 
... 

有了这个,它似乎只要所有用法都与上述指导者在同一个程序集中就可以工作。但是,在你的情况下,他们在不同的程序集。

问题消失,如果你愿意改用空字符串:

public SearchAttribute(SearchDisplay display, string columnName = "") 
... 

否则,我建议你使用旧的前C#-4风格

[Search(SearchAttribute.SearchDisplay.Regular)] 
public Category Category 
... 

[Search(SearchAttribute.SearchDisplay.Regular, ColumnName = "Changed!")] 
public Category AnotherCategory 
... 

这适用于没有columnName参数在构造函数中,只要有一个名为ColumnName的类成员(实例属性或字段)。 ColumnName不得为只读或只读。

+0

你是绝对正确的。错误与代码无关,只是简单地构建顺序?或者丹尼尔A.怀特也正确吗? – Kev 2013-04-08 16:22:50

+0

@Kryptonite我不确定它是否受支持。我会认为这是,但线程[属性和命名/可选构造函数参数不工作](http://stackoverflow.com/questions/8189807/)混淆了我一下。 – 2013-04-08 16:24:45

+0

@Kryptonite更新:堆栈溢出的其他线程同意这是一个错误。看到我上面编辑的答案。 – 2013-04-08 17:25:18

1

不要你的意思

[Search(SearchAttribute.SearchDisplay.Regular)] 
+0

是的,对不起,我的意思是说。编辑。 – Kev 2013-04-08 16:04:21

+0

@Kryptonite尝试从'columnName'中删除默认值。我不认为这是支持。 – 2013-04-08 16:05:17

+0

工作!但为什么??它在我的本地环境(VS2012)上编译得很好... – Kev 2013-04-08 16:13:27