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

时间:2013-04-08 16:00:08

标签: c# asp.net asp.net-mvc

为什么下面的代码给我例外:

  

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构建过程。在属性中使用null值默认参数时会发生a bug in the VS2010 / C#4 compiler。我可以解决这3种方式:

  1. 请勿使用默认参数 - public SearchAttribute(SearchDisplay display, string columnName)
  2. 使用空字符串 - public SearchAttribute(SearchDisplay display,string columnName =“”)
  3. 更新我的构建服务器。
  4. 我刚刚和2一起去。 3是我需要在另一个时间思考的事情。

2 个答案:

答案 0 :(得分:3)

我认为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参数。 <{1}} ColumnName不能是只读或只获取。

答案 1 :(得分:1)

你不是说

 [Search(SearchAttribute.SearchDisplay.Regular)]