如果多个成员具有相同的属性,如何抛出编译器错误

m-y*_*m-y 15 .net c# attributes compiler-errors .net-4.0

简单的问题,如何强制C#编译器抛出编译错误.


更新:也许最好用一个Assert.Fail()代替?

我有一个自定义属性,只应该应用于一个类的一个成员.在我的另一个类的静态方法中,如果有多个成员应用了该属性,它会查找该成员并且我希望它失败(不抛出异常).

public class Foo
{
    [MyCustomAttribute]
    public String FooString { get; set; }

    [MyCustomAttribute]
    public String OtherFooString { get; set; }
}


public class Bar<T>
    where T : class, new()
{
    static Bar()
    {
         //If more than one member of type Foo has MyCustomAttribute
         //applied to it compile error or Assert.Fail()?
    }
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 28

您可以使用诊断指令:

#error Oops. This is an error.
Run Code Online (Sandbox Code Playgroud)

或只是警告:

#warning This is just a warning.
Run Code Online (Sandbox Code Playgroud)

你通常想把它们放在条件块中,我希望......

编辑:好的,现在你已经更新了你的问题,你根本无法在编译时这样做.你的建议是Assert.Fail将问题用于执行时间.

我建议你编写单元测试来检测它(迭代程序集中的所有类型,并检查该属性是否每个类型最多只应用一次).

编辑:在2016年...虽然OP建议的代码分析实际上不是编译器错误,但现在Visual Studio使用Roslyn,使用Roslyn代码挂钩编译器并真正从编译器获得错误是可行的分析仪.不过,我还是个人比较喜欢这个单元测试,那么代码可以构建和测试,任何人,无论他们是否已经安装了罗斯林分析.仍然没有办法用"纯粹的香草"C#编译器验证这一点.


m-y*_*m-y 5

在问了这个问题一年多之后,我实现了单元测试的替代解决方案:代码分析。

如果没有代码分析规则,您甚至可以自己滚动。只需确保将规则设置为“错误”而不是“警告”(或确保将警告视为错误)。这是该屏幕的图像:

代码分析错误

当然,在这种情况下,我仍然更喜欢使用单元测试,但是我绝对可以将代码分析视为一种替代解决方案,尤其是对于自定义命名(例如,我的所有类都应以“ Foo”结尾或抛出错误) )。

  • @JonathanWilson:我可以告诉你,现在我们有了Roslyn,可以将.NET分析器作为NuGet软件包包含在项目中。 (2认同)