Принудительное использование атрибута свойств, если у них уже есть другой атрибут

Я хочу форсировать использование attribute, если используется другой attribute. Если к property присоединен специальный сторонний attribute, этот attribute также необходимо присвоить property. Есть ли возможность сделать это?

Например:

[Some3rdPartyAttribute("...")]
[RequiredAttribute("...)]
public bool Example{get; set;}

не должно приводить к ошибке компиляции,

[Some3rdPartyAttribute("...")]
public bool Example{get; set;}

должен принести ошибку компиляции или предупреждение.

Сам attribute определяется как пример из самого http://msdn.microsoft.com/en-US/library/z919e8tw(v=vs.80).aspx. Но как заставить использование attribute если используется другой attribute?

Ответ 1

Другой вариант - использование некоторых методов АОП. Как например:

PostSharp.

Используя его, вы можете при компиляции проанализировать код yur и исправить ошибку, если какое-то условие не удовлетворяет вашим требованиям.

Для конкретного примера по атрибутам можно посмотреть:

PostSharp 2.1: Отражение пользовательских атрибутов

Ответ 2

К сожалению, вы не можете генерировать настраиваемые предупреждения компилятора из атрибутов. Некоторые атрибуты, такие как System.ObsoleteAttribute, генерируют предупреждение или ошибку, но это жестко закодировано в компиляторе С#. Вы должны найти другое решение своей проблемы, возможно, позволить Some3rdPartyAttribute наследовать от RequiredAttribute?

В противном случае вам придется сменить компилятор.

Ответ 3

Вы можете написать код, который запускается при запуске приложения, который использует отражение, и затем бросает исключения во время выполнения, если атрибут использовался без надлежащего соответствия, но я считаю, что, насколько вы можете идти, и лично я не буду считать, что хороший подход, так как вам нужно будет запустить приложение один раз, чтобы убедиться, что оно соответствует вашим правилам.

Также обратите внимание на PostSharp, который может вам помочь.

Ответ 4

Как насчет использования # warning + Единичное тестирование? Таким образом, всякий раз, когда вы запускаете тесты Unit, выдается предупреждение (или вы можете просто использовать Debug.Fail вместо #warning)

Ответ 5

Вы можете создать консольное приложение, которое будет перебирать все типы в вашем рефлекторе сборки, проверять, удовлетворено ли это правило, и вернуть 0, если это так, и некоторый другой код ошибки и выводить ошибку, если правило нарушено.

Затем запустите это консольное приложение как задачу после сборки.

Ответ 6

Насколько я знаю, нет способа проверить атрибуты во время компиляции.

Мне недавно требовалось принудительное выполнение чего-то подобного (все классы, полученные из определенного базового класса, нуждаются в определенных атрибутах). В результате я положил ручную проверку (с [Conditional("DEBUG")]), используя отражение в конструкторе базового класса. Таким образом, всякий раз, когда кто-то создает экземпляр класса с отсутствующими атрибутами, он получает исключение. Но это может быть неприменимо в вашем случае, если ваши классы не все происходят из одного класса.