Как выбросить ошибку компилятора, если более одного элемента имеет тот же атрибут
Простой вопрос, как заставить компилятор С# вызывать ошибку компиляции.
Обновление: может быть, лучше использовать Assert.Fail()
вместо этого?
У меня есть настраиваемый атрибут, который должен применяться только к элементу ONE класса. Внутри статического метода моего другого класса он ищет этот один элемент, и я хочу, чтобы он терпел неудачу (не генерировал исключение), если к нему применен более чем один элемент.
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()?
}
}
Ответы
Ответ 1
Вы можете использовать диагностическую директиву:
#error Oops. This is an error.
или просто предупреждение:
#warning This is just a warning.
Обычно вы хотите поместить их в условные блоки, я бы ожидал...
EDIT: Хорошо, теперь вы обновили свой вопрос, вы просто не можете сделать это во время компиляции. Ваше предложение использовать Assert.Fail
помещает проблему во время выполнения.
Я бы посоветовал вам написать единичные тесты, чтобы обнаружить это (перебрать все типы в сборке и проверить, что атрибут был применен не более одного раза для каждого типа).
EDIT: в 2016 году... в то время как анализ кода, предложенный OP, на самом деле не является ошибкой компилятора, теперь, когда Visual Studio использует Roslyn, можно подключиться к компилятору и действительно получить ошибку от компилятора, используя анализатор кода Roslyn. Тем не менее, я по-прежнему лично предпочел бы для этого модульные тесты, так как тогда код мог быть построен и протестирован кем угодно, независимо от того, установлен ли у них анализатор Roslyn. Пока еще нет возможности проверить это с помощью "чисто ванильного" компилятора С#.
Ответ 2
Спустя год после того, как этот вопрос был задан, я понял альтернативное решение для модульных тестов: Анализ кода.
Если не существует правила анализа кода, вы можете даже перевернуть свой собственный. Просто убедитесь, что это правило указано как Ошибка, а не Предупреждение (или обязательно обрабатывайте предупреждения как ошибки). Вот изображение этого экрана:
![Code Analysis Error]()
Конечно, я по-прежнему предпочитаю использовать Unit Test в этом конкретном случае, но я могу определенно увидеть Code Analysis в качестве альтернативного решения, особенно для таких вещей, как пользовательское именование (т.е. все мои классы должны заканчиваться на "Foo", или выбросить ошибку).
Ответ 3
Простой ответ: попросите его скомпилировать что-то синтаксически недействительное.
Ответ 4
Я не считаю, что это может быть сделано, потому что невозможно сообщить компилятору проверить наличие ошибок. Конечно, вы можете использовать #error, как сказал Джон, но нет возможности добавить это условие. Поскольку #error вызывает ошибку каждый раз.
Единственное, на что вы можете быть уверены, это проверить во время выполнения и затем исключить исключение.
Изменить: Черт, вопрос, после того как он был сильно отредактирован.