I often end up in a situation where I want to discourage other developers from continuing to use a method or class. For example, let's say I have two library methods "A" and "B" where "A" is the "old" way of doing some task and "B" is the "new" way of doing that task. In many cases, A and B are sufficiently different to make refactoring code using A to start using B non-trivial (e. g. requires flowing through of additional state). Since A works in the cases where it's used, I don't want to prioritize the refactor. I do, however, want to give my fellow developers a visual indication that A is not to be used in new code.
Thus, I'd ideally like the strike-through you get when referencing a member with the ObsoleteAttribute
WITHOUT the associated compiler warning/error (since turning that on would emit hundreds of errors from all the old uses of A that we don't plan to address any time soon). That way, if a developer writes a new line of code with A, he or she will immediately notice the strike-through and fix the code to use B.
Is there any way to get such functionality in VisualStudio (2012)?
EDIT:
There have been several comments to the effect of "there's no way to distinguish between new and old code". I agree. However, that's not what I'm asking for, so let me clarify: instead, what I want is a visual representation of code being "out of date" (e. g. strikethrough) without the corresponding compiler warning or error. That way, developers in the process of reading old code or writing new code will get an immediate visual indication that something is out of date. Even if this isn't supported natively in .NET, maybe there is a VS extension out there for this purpose?
There have been several comments to the effect of "you can't both have a warning and not have a warning". I thought I explained the use case above, but I'll give it another try. We have a set of core libraries which are used heavily throughout the various solutions that comprise our code base. Sometimes, I make an update to one of these libraries which provides a new, better API for performing some task. To maintain backwards compatibility, I can't just remove the old way of doing that task (in many cases), since tons of existing code relies on using the old set of APIs and can't be trivially refactored to use the new one. Furthermore, there's no pressing reason to do so; it would just risk introducing bugs into existing code. However, I'd like some way of visually alerting developers to the fact that certain APIs should be avoided in favor of other ones. This is difficult, since developers tend to learn how to accomplish some task by reading existing code that accomplishes the same task. That makes new APIs hard to spread, since the old entrenched APIs are referenced by so much existing code. The
ObsoleteAttribute
achieves this via compiler warnings, but those warnings will just create tons of noise from the hundreds of existing uses of the old APIs. That's why I like the strikethrough: it's something that is very visual and yet it will only intrude on a developer when he or she is reading or writing code that uses an out of date API. Here are some examples of changes where I wanted to mark an old API:- We introduced a new API for running SQL queries that is less verbose, less quirky, and more flexible than what we had previously. It's hard to outright remove the old API because it has so many quirky behaviors that might be relied on. However, I want to push people towards the new API for future development.
- We have two internal sets of unit test helper APIs. The older one is perfectly functional, but it depends on inheritance and is not very flexible. The newer one is built using attributes and is more flexible. Hundreds of old tests still run using the old API, but I want to push writers of new tests to use the new API.
- Our core libraries have some old random legacy code that doesn't really fit but would be difficult to remove at this point. I'd like to curtail the adding of new references to these types and methods. That way, it may become cost effective to remove them at some point as the existing code that depends on them disappears due to normal churn.
As a further note, I think the answer to this question does a good job of describing why you might not mark something obsolete even though you wouldn't recommend using it in new code.
There are several comments/answers simply calling out the existence of the
ObsoleteAttribute
. Please note that the text of this question has always referenced that attribute.