Как вы можете пометить код как "не для будущего использования"

Я часто оказываюсь в ситуации, когда я хочу отговорить других разработчиков от продолжения использования метода или класса. Например, допустим, у меня есть два библиотечных метода "A" и "B", где "A" - это "старый" способ выполнения некоторой задачи, а "B" - "новый" способ выполнения этой задачи. Во многих случаях A и B достаточно различаются, чтобы сделать рефакторинг кода с использованием A, чтобы начать использовать B нетривиально (например, требует прохождения дополнительного состояния). Поскольку А работает в тех случаях, когда он используется, я не хочу расставлять приоритеты рефакторинга. Я, однако, хочу дать своим коллегам-разработчикам визуальное указание на то, что A не будет использоваться в новом коде.

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

Есть ли способ получить такую ​​функциональность в VisualStudio (2012)?

РЕДАКТИРОВАТЬ:

  • Было несколько комментариев о том, что "нет никакого способа различить новый и старый код". Согласен. Однако это не то, о чем я прошу, поэтому позвольте мне уточнить: вместо этого мне нужно визуальное представление кода, который "устарел" (например, зачеркнутый) без соответствующего предупреждения или ошибки компилятора. Таким образом, разработчики в процессе чтения старого кода или написания нового кода получат немедленную визуальную индикацию того, что что-то устарело. Даже если это не поддерживается изначально в.NET, может быть, есть расширение VS для этой цели?

  • Было несколько комментариев о том, что "вы не можете одновременно иметь предупреждение и не иметь предупреждения". Я думал, что объяснил пример использования выше, но я попробую еще раз. У нас есть набор базовых библиотек, которые интенсивно используются в различных решениях, составляющих нашу кодовую базу. Иногда я делаю обновление для одной из этих библиотек, которая предоставляет новый, лучший API для выполнения какой-либо задачи. Чтобы поддерживать обратную совместимость, я не могу просто удалить старый способ выполнения этой задачи (во многих случаях), поскольку тонны существующего кода основаны на использовании старого набора API-интерфейсов и не могут быть тривиально реорганизованы для использования нового. Кроме того, нет веской причины для этого; он просто рискует внести ошибки в существующий код. Тем не менее, я хотел бы, чтобы какой-то способ визуально предупредил разработчиков о том, что следует избегать определенных API в пользу других. Это сложно, поскольку разработчики, как правило, учатся выполнять некоторые задачи, читая существующий код, который выполняет ту же задачу. Это затрудняет распространение новых API, поскольку на старые укоренившиеся API ссылается так много существующего кода. ObsoleteAttribute достигает этого с помощью предупреждений компилятора, но эти предупреждения просто создадут тонны шума от сотен существующих применений старых API. Вот почему мне нравится зачеркивание: это что-то очень наглядное, и, тем не менее, оно будет навязываться разработчику только тогда, когда он или она читает или пишет код, использующий устаревший API. Вот несколько примеров изменений, где я хотел отметить старый API:

    • Мы представили новый API для выполнения SQL-запросов, который является менее многословным, менее изворотливым и более гибким, чем у нас ранее. Трудно полностью удалить старый API, потому что в нем так много странных действий, на которые можно было бы положиться. Тем не менее, я хочу подтолкнуть людей к новому API для будущего развития.
    • У нас есть два внутренних набора вспомогательных API тестов модулей. Более старый отлично функционирует, но зависит от наследования и не очень гибок. Более новый построен с использованием атрибутов и является более гибким. Сотни старых тестов по-прежнему выполняются с использованием старого API, но я хочу подтолкнуть авторов новых тестов к использованию нового API.
    • Наши базовые библиотеки имеют некоторый старый случайный унаследованный код, который на самом деле не подходит, но на данном этапе его будет трудно удалить. Я хотел бы ограничить добавление новых ссылок на эти типы и методы. Таким образом, в какой-то момент их удаление может стать экономически эффективным, поскольку существующий код, который зависит от них, исчезнет из-за нормального оттока.
  • В качестве дальнейшего примечания, я думаю, что ответ на этот вопрос хорошо описывает, почему вы не можете пометить что-то устаревшее, даже если бы вы не рекомендовали использовать его в новом коде.

  • Есть несколько комментариев / ответов, просто призывающих к существованию ObsoleteAttribute, Обратите внимание, что текст этого вопроса всегда ссылался на этот атрибут.

4 ответа

Решение

Добавление атрибута " Устаревший" в ваш метод даст зачеркивание в intellisense.

[ObsoleteAttribute("This property is obsolete. Use NewProperty instead.", false)] 
public static string OldProperty
{ get { return "The old property value."; } }

Чтобы отключить предупреждения, добавьте это перед атрибутом:

#pragma warning disable 612, 618

И чтобы включить:

#pragma warning restore 612, 618

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

<WarningsNotAsErrors>618</WarningsNotAsErrors>

РЕДАКТИРОВАТЬ: Кроме того, проверьте @JonHanna ответ об использовании EditorBrowsable атрибут

Как уже отмечали другие, на самом деле есть 2 предупреждения, которые выбрасываются с устаревшим атрибутом.

РЕДАКТИРОВАТЬ:

#pragma warning disable 612, 618
[Obsolete]
#pragma warning restore 612, 618
public class test1
{...

Когда вы пытаетесь использовать test1 ты получишь:

Обратите внимание, что при вводе var test = new test1() зачеркивание не происходит.

Но test1 test = new test1() покажет зачеркнутый.

Итак, вы хотите предупреждение, но без каких-либо предупреждений?

Основная проблема здесь заключается в том, что при компиляции нет ничего, что отличало бы "старый код, прежде чем мы думали о нем лучше", от "нового кода, который не должен использовать старые привычки"; это всего лишь код.

Единственное, что вы можете сделать, это использовать ObsoleteAttribute а затем использовать #pragma warning disable 612, 618 на текущем использовании. Как всегда, #pragma warning никогда не должно существовать без комментария:

#pragma warning 612, 618 //This block of code uses BadOldMethod(), code review planned
/* ... code here */
#pragma warning restore 612, 618

Конечно, если есть веская причина прекратить его использовать, есть веская причина сделать этот обзор раньше, а не позже.

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

Дальнейшее разочарование может быть связано с маркировкой участника как [EditorBrowsable(EditorBrowsableState.Never)], Тот факт, что метод не будет отображаться в intellisense вообще, в то время как новый будет, подтолкнет людей к новому (при условии, что библиотека упоминается как библиотека, а не как проект в решении или класс в рамках одного проекта).

Используйте устаревший атрибут.

[ObsoleteAttribute("This method is obsolete. Call NewMethod instead.", false)] 
public string SomeObsoleteMethod()
{
   // ...
}

Последний аргумент (IsError) выдаст ошибку компиляции, если установлено trueв противном случае будет дано предупреждение. Вы можете отключить предупреждения с помощью #pragma 612, 618

РЕДАКТИРОВАТЬ:

Хорошо, хорошо, я смягчаюсь. Решение, которое вы хотите, выглядит следующим образом:

/// <summary>
/// Please don't use
/// </summary>
public string SomeObsoleteMethod()
{
   // ...
}

Нет поддержки компилятора вообще.

Лично я думаю, что вы должны использовать ObsoleteAttribute, убедившись, что вы используете #pragma (см. здесь примеры), чтобы отключить его там, где это необходимо в существующем коде.

Со временем вы исправите код.

Другие вопросы по тегам