Monday 20 April 2009

The Obsolete Attribute

Today a former co-worker asked me “what was that attribute we used to mark something as deprecated?” After a little pause for thought I remembered it was the ObsoleteAttribute- It’s a shame Microsoft hadn’t named this DeprecatedAttribute instead- this is what the annotation is called in Java.

I had previously used this attribute whilst in the middle of a large refactoring exercise on a project, where other developers were working on existing classes. It served as a useful reminder to start calling the new method, without breaking the build/their code/unit tests (we had a team culture where we would address warnings as soon as we noticed them). After all the consumer classes had been modified to use the new code, I searched for “Obsolete” in the code and discovered that the previous development team (the project was initially outsourced) had been using comments to mark code as deprecated- so perhaps not many people know about this useful attributes existence?

By default the attribute generates a compiler warning when a program element is referred to in a consumer class. This is the way I had used the attribute previously with a textual description describing how to correct the warning. Indeed a first glance at the documentation for the class (see here in the C# language specification, and here in the MSDN library)  suggests this is all this attribute can do:

        static void Main(string[] args)

        {

            ObsoleteOne();

        }

 

        [Obsolete("Use the BetterMethod instead")]

        public static void ObsoleteOne()

        {

            Console.WriteLine("This is a bad method");

        }

 

        public static void BetterMethod()

        {

            Console.WriteLine("This is a better method");

        }

 

 

Used in this manner, the attribute will caused a warning to be generated like so:

image

In our discussion on using the attribute my former co-worker pointed out that the attribute can also be used to create a compiler error, simply by changing the code to (notice the 2nd boolean parameter):

        [Obsolete("Use the BetterMethod instead", true)]

        public static void ObsoleteOne()

        {

            Console.WriteLine("This is a bad method");

        }

This will result in a compiler error as follows:

image

In my project I didn’t use this- when references to the old code were removed, I simply removed the obsolete methods. In an API which you distribute to multiple consumers, you obviously don’t have that luxury, and I can see this overload being useful. It is important to remember that this attribute is useful for classes, structs, enums, constructors, properties, fields, events, interfaces or delegates as well as methods.

Sun’s (or should I say Oracle’s) Java documentation provides some useful insight as to when you should deprecate code.

When deprecating it is important to suggest how developers using your code should fix the issue. For example if you use the deprecated class System.Web.Mail.MailMessage, you will receive the following useful compiler warning:

image

This tells the consumer that the method is obsolete, what the recommended alternative is and where to go to find further help- which unfortunately in this case seems to redirect to a generic .NET Framework page (woops)! I’m sure any competent developer can quickly work out that they should use System.Net.Mail.MailMessage instead though!

No comments:

Post a Comment