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:
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.
Adding the Obsolete attribute to your method will give the strikethrough in intellisense.
[ObsoleteAttribute("This property is obsolete. Use NewProperty instead.", false)]
public static string OldProperty
{ get { return "The old property value."; } }
To disable the warnings add this before the attribute:
#pragma warning disable 612, 618
And to reenable:
#pragma warning restore 612, 618
As noted here, putting a ignore in your project file instead of in your code would be a very clean solution.
<WarningsNotAsErrors>618</WarningsNotAsErrors>
EDIT: Also, check out @JonHanna's answer about using the EditorBrowsable
attribute.
As others have noted, there are actually 2 warnings that are thrown with the obsolete attribute.
EDIT:
#pragma warning disable 612, 618
[Obsolete]
#pragma warning restore 612, 618
public class test1
{...
When you try to use test1
you will get:
Note that when you type var test = new test1()
the strikethrough does not occur.
But test1 test = new test1()
will show the strikethrough.