Проверить, есть ли у класса атрибут?


102

Я пытаюсь выполнить небольшую разработку Test-First, и я пытаюсь проверить, что мои классы отмечены атрибутом:

[SubControllerActionToViewDataAttribute]
public class ScheduleController : Controller

Как я могу модульно проверить, что классу назначен этот атрибут?

Ответы:


124

Проверь это

Attribute.GetCustomAttribute(typeof(ScheduleController),
    typeof(SubControllerActionToViewDataAttribute))

не является нулевым ( Assert.IsNotNullили аналогичным)

(Причина, по которой я использую это, а не в IsDefinedтом, что в большинстве случаев я хочу также проверить некоторые свойства атрибута ....)


6
только для проверки наличия атрибута, что обычно является всем, что необходимо для атрибутов без параметров / без свойств, дешевле использовать .IsDefined, поскольку он будет запрашивать метаданные, а не десериализовать и создать экземпляр объекта атрибута.
— Лассе В. Карлсен,

1
Дело в том, что IsDefined дешевле ... но в большинстве случаев (и в частности в модульных тестах) вы вряд ли заметите разницу. Может быть, если бы это был жесткий цикл в производственном коде ...
— Марк Грейвелл

@ Marc - Я согласен с тем, что разница в производительности, вероятно, не будет заметна в модульном тесте. Я бы получил атрибут, если бы мне нужно было его использовать, что, как вы говорите, является сценарием в большинстве случаев. Недавно я использовал IsDefined во фреймворке, который писал, чтобы исключить столбец из раскрывающегося списка сортируемых полей - это сработало хорошо, так как мне не нужно было использовать сам атрибут.
— RichardOD

Как мы можем проверить то же самое для метода?
— Манвиндер Сингх,

81

То же самое, что вы обычно проверяете для атрибута в классе.

Вот пример кода.

typeof(ScheduleController)
.IsDefined(typeof(SubControllerActionToViewDataAttribute), false);

Я думаю, что во многих случаях проверка наличия атрибута в модульном тесте неверна. Поскольку я не использовал функциональные возможности субконтроллера MVC contrib, я не могу прокомментировать, подходит ли это в данном случае.


Сделал +1, а потом заметил ошибку. Это должно быть .IsDefined (typeof (Type), false);
— Александр Белецкий

@alexanderb вы конечно правы. Я обновил свой ответ сейчас. Я не должен проверять свой ответ компилятором в то время! Спасибо за указание на ошибку
— RichardOD

10
этот подход быстрее, чем предыдущий
— Слава

18

Здесь также можно использовать дженерики:

var type = typeof(SomeType);
var attribute = type.GetCustomAttribute<SomeAttribute>();

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


У меня это не работает. Что using.. я скучаю?

@Scanzy Я не уверен, вы не используете IDE? (Обычно они подсказывают правильное using) Какую ошибку вы получаете?
— Kroltan

1
хорошо, здесь я обнаружил, что GetCustomAttribute<SomeAttribute>метод доступен из .NET 4.5, и моя IDE была установлена ​​на 3.5, так что теперь все ясно

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.