将默认字符串参数传递给特性导致的C#编译器错误

本文关键字:编译器 错误 字符串 默认 参数传递 | 更新日期: 2023-09-27 18:07:59

为什么下面的代码会给我一个异常:

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年的版本。

更新

多亏了下面的回答者,我明白了:

我正在使用VS2012,但生成服务器仍在使用VS2010生成过程。当在属性中使用空值默认参数时,VS2010/C#4编译器中会出现一个错误。我可以绕过这3种方法:

  1. 不使用默认参数-public SearchAttribute(SearchDisplay display, string columnName)
  2. 使用空字符串-public SearchAttribute(SearchDisplay显示,字符串columnName="(
  3. 更新我的生成服务器

我现在和2一起去。3是我需要在另一个时间考虑的事情。

将默认字符串参数传递给特性导致的C#编译器错误

我认为Customer.cs文件在一个单独的程序集(C#项目(中,该程序集引用SearchAttribute.cs所在的程序集。

为了使枚举SearchDisplay和构造函数中的可选参数columnName正常工作,必须按照正确的顺序重新编译这两个程序集。我怀疑您的构建服务器上并非如此。依赖程序集可能是通过引用SearchAttribute所在程序集的旧版本编译的。

更新

查看右侧的所有链接线程。他们说这是一个用Visual Studio 2012(C#5编译器(修复的错误。只有当可选参数的默认值为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不得为只读或仅获取。

你不是说吗

 [Search(SearchAttribute.SearchDisplay.Regular)]