Рассмотрим простой пример как это работает. Обычно подобное возникает в двух ситуациях:
- Пусть в самом начале класс Example1 содержал только метод Old(), которым все успешно пользовались, спустя какое-то время, Вы понимаете, что скорость работы метода Old() довольно низкая, поэтому решаете реализовать новую версию старого метода - метод New(), который делает тоже самое, но гораздо быстрее. Конечно, в качестве совместимости, вы обязаны оставить метод Old() и New().
- Эта ситуация очень похожа на предыдущую, у нас есть старый метод VeryOld() и новый New(), но с одним отличием, метод VeryOld() настолько устарел, что использование его стало недопустимым. Это означает, что метод VeryOld() подлежит удалению из класса Example2.
class Example1
{
/// <summary>
/// Данный метод использовать можно, но не рекомендуется.
/// </summary>
[Obsolete("Используй New()")]
public void Old() { }
/// <summary>
/// Свежая версия метода Old().
/// </summary>
public void New() { }
}
class Example2
{
/// <summary>
/// Данный метод использовать нельзя.
/// </summary>
[Obsolete("Используйте New()", true)]
public void VeryOld() { }
/// <summary>
/// Заменяющая версия метода VeryOld().
/// </summary>
public void New() { }
}
После чего, во время компиляции кода, где будет происходить использование устаревших методов будет возникать предупреждение (warning) компиляции с текстом предупреждения:
Example1 e1 = new Example1();
e1.New(); // Без предупреждений и ошибок.
e1.Old(); // С предупреждением "Используй New()".
или ошибка (error) компиляции тоже с текстом предупреждения:
Example2 e2 = new Example2();
e2.New(); // Без предупреждений и ошибок.
e2.VeryOld(); // Выдаст ошибку компиляции с сообщением "Используйте New()".
Это и есть основное предназначение атрибута Obsolete. Но существует и другой интересный способ использования данного атрибута, до тех пор, пока в .NET не будет атрибута "Этот код нуждается в рефакторинге":
[Obsolete("Нуждается в рефакторинге.")]
public class RefactoringAttribute : Attribute { }
и использовать этот атрибут в качестве маркера кода, который нужно отрефакторить:
class Example3
{
/// <summary>
/// Метод нуждающийся в рефакторинге.
/// При компиляции, будет предупреждение.
/// </summary>
[Refactoring]
public void Ugly() { }
/// <summary>
/// Класс который нуждается в рефакторинге.
/// При компиляции, будет предупреждение.
/// </summary>
[Refactoring]
class UglyClass { }
}
Причем в самом коде, где мы используем ugly-методы никаких предупреждений нет, только на уровне описания.
Example3 e3 = new Example3();
e3.Ugly(); // Здесь без предупреждений и ошибок.
Хорошая статья! Спасибо.
ОтветитьУдалитьМне только один момент непонятен (я просто не разбирался в пользовательских атрибутах, поэтому просто скажите, правильно ли я догадался): когда мы пишем
[Obsolete("Нуждается в рефакторинге.")]
public class RefactoringAttribute : Attribute { }
То такая запись автоматически дает нам атрибут [Refactoring]?
@Andrey Stukalin
ОтветитьУдалитьСпасибо за отзыв. Да, если класс RefactoringAttribute доступен (см. пространство имен), то можно использовать [Refactoring] или [RefactoringAttribute] - это одно и то же.
Спасибо! Буду использовать:)
ОтветитьУдалитьСтатья полезная, понравилась
ОтветитьУдалитьКак советы начинающим или мысли чайника вслух пойдёт, но не больше. Во втором случае проще пользовать #warning и вставлять его куда угодно (да хоть среди комментариев)
ОтветитьУдалитьХорошая идея. Приму на вооружение.
ОтветитьУдалитьспасибо за статью)))
ОтветитьУдалитьИспользование вашего атрибута Refactoring очень сомнительное, если честно.
ОтветитьУдалить@Сергей Звездин
ОтветитьУдалитьЭто потому что мы ввели его искусственным образом.
Согласен с Сергеем Звездиным. Я бы тоже применил лучше препроцессор #warning или комментарий //TODO: Refactor this
ОтветитьУдалить