Создайте атрибут, чтобы сломать сборку

StackOverflow https://stackoverflow.com/questions/28150

  •  09-06-2019
  •  | 
  •  

Вопрос

Хорошо, это вытекает из мой предыдущий вопрос.

Что мне действительно хотелось бы сделать, так это создать какой-то атрибут, который позволит мне украсить метод, который будет сломать конструкцию.Очень похоже на Устарело («причина», правда) атрибут, но без ложной идентификации устаревшего кода.

Чтобы уточнить:Я не хочу, чтобы это разрушило построение ЛЮБОЙ Нажмите F6 (Build), я хочу, чтобы сборка прерывалась только в том случае, если метод, украшенный атрибутом, вызывается где-то еще в коде.Как я и сказал, похожий устаревший, но не тот.

Я знаю, что я не одинок в этом, поскольку другие пользователи хотят использовать его по другим причинам.Я никогда раньше не создавал собственные атрибуты, так что для меня это все в новинку!

Это было полезно?

Решение

Если это для сериализации XML и NHibernate, где вы хотите, чтобы конструктор без параметров был доступен (как в случае с пример вы ссылались), затем используйте частный или защищенный конструктор без параметров для сериализации или защищенный конструктор для NHibernate.Используя защищенную версию, вы открываете возможность унаследованным классам вызывать этот код.

Если вы не хотите, чтобы код вызывал метод, не делайте его доступным.

РЕДАКТИРОВАТЬ:Чтобы, возможно, ответить на более глубокий вопрос, AFAIK компилятор знает только о трех атрибутах: Устаревшие, условные и использование атрибутов.Чтобы добавить специальную обработку для других атрибутов, потребуется изменить компилятор.

Другие советы

Я думаю, что это был бы отличный запрос на добавление функции для Microsoft:Создайте атрибут абстрактного базового класса CompilerExecutedAttribute что компилятор каким-либо образом обрабатывает или может повлиять на процесс компиляции.Затем мы могли бы наследовать этот атрибут и реализовывать различные операции, например.выдать ошибку или предупреждение.

Если вы считаете, что предупреждение (которое выдает [Устарело]) нарушает сборку, просто используйте #предупреждение директива компилятора.

Редактировать:Я никогда не использовал его, но #ошибка также доступен.

Я думаю, что единственным надежным способом было бы расширить Visual Studio (через VSIP) и подписаться на правильное событие (возможно, в классе EnvDTE.BuildEvents), а также проверить свой код на использование конструктора и отменить сборку, если вы обнаружить это.

Все это начинает немного походить на Вчерашний TDWTF. :-)

Я вынужден согласиться с Грегом:создайте для него атрибут.

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

Я бы предложил вам использовать директиву #error.

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

[Conditional("CONDITION")] 
public static void MiMethod(int a, string msg)

который удалит вызов метода из самого IL-кода, если определено «MY_CONDITION».

Создайте правило FxCop и добавьте FxCop в свою интеграционную сборку, чтобы проверить это.

Вы получите предупреждения, а не неудачную сборку.Атрибуты «запускаются» во время отражения, а не во время сборки.

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

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

Отвечаю спустя 4 года :)

У меня был тот же вопрос, есть ли альтернатива устаревшему.

Насколько я помню (видео на канале 9), некоторое время назад Microsoft заявила, что в какой-то момент она работает над предоставлением разработчикам доступа к чему-то вроде API компилятора, поэтому в будущем вполне возможно, что вы сможете написать «плагин» компилятора, который позволит украсить методы своим собственным атрибутом и сообщить компилятору об отмене, если кажется, что декорированный код может вызываться где-то еще в коде и т. д.

Что на самом деле было бы довольно круто, если подумать.Это также напоминает мне, что мне также следует попытаться прочитать о ходе работы над API-интерфейсом компилятора, над которым работает MS...

Почему бы просто не придумать что-нибудь?Неизвестный атрибут наверняка сломает сборку.

[MyMadeUpAttributeThatBreaksTheBuildForSure]
public class NotDoneYet {}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top