Как вызвать ошибку компилятора, если более одного члена имеют один и тот же атрибут - PullRequest
12 голосов
/ 07 июня 2011

Простой вопрос, как вы заставляете компилятор 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()?
    }
}

Ответы [ 4 ]

26 голосов
/ 07 июня 2011

Вы можете использовать диагностическую директиву:

#error Oops. This is an error.

или просто для предупреждения:

#warning This is just a warning.

Обычно вы хотите поместить их в условные блоки, я ожидаю...

РЕДАКТИРОВАТЬ: Хорошо, теперь вы обновили свой вопрос, вы просто не можете сделать это во время компиляции.Ваше предложение использовать Assert.Fail указывает на проблему во время выполнения.

Я бы посоветовал вам написать модульные тесты, чтобы обнаружить это (перебрать все типы в сборке и проверить, что атрибут был применен только вчаще всего один раз для каждого типа).

РЕДАКТИРОВАТЬ: в 2016 году ... хотя анализ кода, предложенный ОП, на самом деле не является ошибкой компилятор , теперь, когда Visual Studio использует Roslyn, это возможноподключиться к компилятору и действительно получить ошибку от компилятора, используя анализатор кода Roslyn.Тем не менее, я бы все же лично предпочел бы для этого модульные тесты, поскольку тогда любой мог бы создавать и тестировать код независимо от того, установлен ли у них анализатор Roslyn.До сих пор нет способа проверить это с помощью «чисто ванильного» компилятора C #.

4 голосов
/ 15 марта 2013

Через год после того, как этот вопрос был задан, я реализовал альтернативное решение для модульных тестов: Анализ кода.

Если не существует правила анализа кода, вы можете даже свернуть свое собственное ,Просто убедитесь, что для правила установлено значение «Ошибка», а не «Предупреждение» (или обрабатывайте предупреждения как ошибки).Вот изображение этого экрана:

Code Analysis Error

Конечно, я все же предпочел использовать модульный тест в этом конкретном случае, но я определенно могу видеть Анализ кода как альтернативное решение,особенно для таких вещей, как пользовательское именование (т.е. все мои классы должны заканчиваться на 'Foo' или выдавать ошибку).

2 голосов
/ 07 июня 2011

Простой ответ: попросите его скомпилировать что-нибудь синтаксически неверное.

1 голос
/ 07 июня 2011

Я не верю, что это можно сделать, потому что невозможно указать компилятору проверять наличие пользовательских ошибок.Конечно, вы можете использовать #error, как сказал Джон, но нет способа добавить само условие.Потому что #error будет каждый раз вызывать ошибку.

Единственное, в чем вы можете быть уверены, это проверить во время выполнения, а затем выдать исключение.

Редактировать: Черт, дойти до вопроса после того, как оно былоСильно отредактировано.

...