【问题标题】:C# Compiler error caused by passing default string parameter to attribute将默认字符串参数传递给属性导致的 C# 编译器错误
【发布时间】:2013-04-08 16:00:08
【问题描述】:

为什么下面的代码给了我异常:

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

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

我现在要带 2 个。 3 是我需要在其他时间考虑的事情。

【问题讨论】:

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


【解决方案1】:

我认为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 = "")
...

否则,我建议你使用旧的 pre-C#-4 样式

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

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

只要有一个名为ColumnName 的类成员(实例属性或字段),就可以在构造函数中没有columnName 参数的情况下工作。 ColumnName 不能是只读的或只读的。

【讨论】:

  • 你是绝对正确的。错误与代码无关,而只是构建顺序?还是 Daniel A. White 也正确?
  • @Kryptonite 我不确定它是否受支持。我想是的,但线程 Attributes and Named/Optional constructor parameters not working 让我有点困惑。
  • @Kryptonite 更新:Stack Overflow 上的其他线程同意这是一个错误。请参阅上面我编辑的答案。
【解决方案2】:

你不是说

 [Search(SearchAttribute.SearchDisplay.Regular)] 

【讨论】:

  • 是的,对不起,我是这个意思。已编辑。
  • @Kryptonite 尝试从columnName 中删除默认值。我认为不支持。
  • 你的构建服务器在运行什么?
  • @Kryptonite 没有编译器和 .net 版本? 4.5 安装了吗?
  • 没有。 VS 和服务器都没有 4.5。我的解决方案中的所有项目都针对 4.0。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-07
  • 1970-01-01
  • 1970-01-01
  • 2011-02-15
  • 2021-12-28
  • 2020-08-04
相关资源
最近更新 更多