In response to a recent thread The Good and the Bad: Obsoletion in the Framework and LOTs of internal discussion, I have written this short whitepaper that describes the intent of using obsolete in the .NET Framework and how it affects your development projects. I believe that that paper balances some of our customer’s requirements that we continue to improve and evolve the .NET Framework with our commitment to provide backwards compatibility in order to preserve customer investments in the .NET Framework today for years to come.
I want to stress that this is just a DRAFT paper… It is not Microsoft’s official position yet. I am still in the process of getting feedback internally and, with this blog entry, externally as well. Please do give me your feedback.
When migrating source code from V1.0 or V1.1 of the Framework to V2.0 you may see some new compiler warnings indicating that you are using types or members that are obsolete. Generally speaking, this warning does NOT indicate that your code will not work well on version 2.0 of the .NET Framework but it does provide some suggestions for updates to your code that Microsoft recommends you make. Microsoft makes every effort to ensure that your V1.0 and V1.1 based applications run as expected on new versions of the .NET Framework. The obsolete warnings highlight where there is some new functionality in the platform that your program could benefit from using. This brief paper describes some strategies for dealing with these warnings in the least disruptive way. In summary:
Microsoft marks types and members in the .NET Framework as being obsolete (by applying the ObsoleteAttribute) to indicate that there is some new functionality in the Framework that Microsoft recommends you migrate to. When used in the .NET Framework, these obsolete warnings do NOT indicate that your source code will not function properly or that Microsoft will definitely be removing these members in the near future. Microsoft remains committed to backwards compatibility of the .NET Framework in order to ensure that investments you make on the framework today continue to pay off for many years in the future.
What does Obsolete mean in the Framework?
When used in the .NET Framework, the obsolete warnings indicate that there is some new feature of the framework which you should consider migrating to. In many cases by simply changing the functions you call in the framework to the suggested alternative you can make your application more secure, performant or reliable. However in some cases it may not be worth the development costs to move to the new functionality. You can make that determination by understanding the impact of the change on your source code and the benefits as described in the warning text and the linked help page.
In some extreme cases Microsoft will be forced to actually remove an obsolete member in a future version of the .NET Framework. This is likely to be a very rare case. When this is the intent the member will be marked with Error=True in the ObsoleteAttribute indicating that a compiler error (rather than warning) should be generated. You are strongly recommended to migrate your projects off these members to ensure they work seamlessly on future versions of the .NET Framework.
The code below shows an example of using an obsolete member. This code compiles without warnings under V1.1, but when migrated to V2.0 it generates a warning as shown.
public class SampleOld
public static void Main1()
XmlSchemaCollection xsc = new XmlSchemaCollection();
xsc.Add(null, "schema1.xsd"); //Adds schema & compiles
xsc.Add("ns-a", "schema2.xsd"); //adds schema & compiles all schemas
foreach (XmlSchema schema in xsc)
Console.WriteLine("Schema in Coll: " + schema.TargetNamespace);
} // End class
[VB]Imports System.XmlImports System.Xml.SchemaPublic Module SampleOld Public Sub Main1() Dim xsc As New XmlSchemaCollection() xsc.Add(Nothing, "schema1.xsd") xsc.Add("ns-a", "schema2.xsd") For Each schema As XmlSchema In xsc Console.WriteLine("Schema in Coll: " & schema.TargetNamespace) Next End SubEnd Module
It generates these warning:
Warning 1 'System.Xml.Schema.XmlSchemaCollection' is obsolete: 'Consider using System.Xml.Schema.XmlSchemaSet for schema compilation and validation. http://go.microsoft.com/fwlink/?linkid=14202' ObsoleteExample.cs 9 8
Warning 2 'System.Xml.Schema.XmlSchemaCollection' is obsolete: 'Use System.Xml.Schema.XmlSchemaSet for schema compilation and validation. http://go.microsoft.com/fwlink/?linkid=14202' ObsoleteExample.cs 9 38
Reading the information on the link you will discover that XmlSchemaSet was obsoleted for these reasons:
As you see from the warning text and information on the website indicated, the fix is trivial:
using System.Xml.Schema ;
public class SampleNew
public static void Main()
XmlSchemaSet set = new XmlSchemaSet();
set.Compile(); //Add multiple schemas and explicitly call compile
foreach (XmlSchema schema in set.Schemas())
Console.WriteLine("Schema in set: " + schema.TargetNamespace);
[VB]Imports System.XmlImports System.Xml.SchemaPublic Module SampleNew Public Sub Main() Dim xset As New XmlSchemaSet() xset.Add(Nothing, "schema1.xsd") xset.Add("ns-a", "schema2.xsd") xset.Compile()'Add multiple schemas and explicitly call compile For Each schema As XmlSchema In xset.Schemas() Console.WriteLine("Schema in Coll: " & schema.TargetNamespace) Next End SubEnd Module
Obsolete and /warnaserror+
Many development teams consider it a best practice to compile with warnings as errors. This practice ensures that all warnings are resolved and any potential issues are addressed. The VB and C# compilers generate a warning for usage of obsolete members of the framework with text that describes the new functionality that you should consider using instead. As we describe above, it may not always make sense to immediately fix these warnings. For teams that compile with warnings as errors (/warnaserror+) this posses a problem as these obsolete warnings are turned into errors which must be addressed. As such Microsoft recommends that teams using /warnaserror+ also use /nowarn:0618 (for C#) or /nowarn:40000 (for VB) to suppress the obsolete messages. Although explicitly turning off all warnings of a certain class is not generally considered good development practice in this case it is the preferred way to handle this situation.
You will of course want to review your usage of obsolete members and decide which ones to fix. Under this plan the preferred way to do that is to use FxCop which contains a rule “ConsiderNotUsingObsoleteFunctionality”. By running FxCop over your project with this rule on you are able to triage the issues out of band of the mainline development process.
This code sample shows how this process would work. This code compiles without warnings under V1.1 and continues to under V2.0 if compiled as shown below.
C:\ObsoleteExample>csc /warnaserror+ /nowarn:0618 old.cs
C:\ObsoleteExample>vbc /warnaserror+ /nowarn:40000 class1.vb
Alternatively in C#, you can use the #pragma around the offending lines to keep the compiler from issuing a warning or error. As shown here:
public static void Main()
#pragma warning disable 0618
#pragma warning restore 0618
As you see, we got no warnings or errors in either case. Out of band of the official build you may want to run FxCop to flag potential problems and fix the appropriate ones.
C:\ObsoleteExample>fxcopcmd /rid:Usage# ConsiderNotUsingObsoleteFunctionality /f:old.exe /console
Warning : ConsiderNotUsingObsoleteFunctionality: SampleOld old.cs(9,8): This member is Obsolete. "Consider using System.Xml.Schema.XmlSchemaSet for schema compilation and validation."
This mechanism allows you to migrate to new versions of the .NET Framework easily while also being aware of new features of the .NET Framework that maybe worth considering.