Don't use obsolete types, methods or fields

Rule ND1311 Design

Warns about methods using a type, method or field tagged with System.ObsoleteAttribute: such API elements will be removed sooner or later and shouldn't be used.

How to fix

Follow the workaround message typically provided with System.ObsoleteAttribute to avoid the obsolete element.

Estimated Debt: 5 minutes per type, method or field used. Severity is High: it is important to no longer rely on obsolete code.

CQLinq source

This rule is written in CQLinq, C# LINQ over the NDepend code model. It ships with every new NDepend project: you can read it, adapt it, or use it as a starting point for your own custom rules.

// <Name>Don't use obsolete types, methods or fields</Name>   
// <Id>ND1311:DontUseObsoleteTypesMethodsOrFields</Id>

warnif count > 0
let obsoleteTypes      = Types     .Where(t => t.IsObsolete).ToHashSetEx()
let obsoleteMethods    = Methods   .Where(m => m.IsObsolete).ToHashSetEx()
let obsoleteFields     = Fields    .Where(f => f.IsObsolete).ToHashSetEx()
let obsoleteProperties = Properties.Where(p => p.IsObsolete).ToHashSetEx()
let obsoleteEvents     = Events    .Where(e => e.IsObsolete).ToHashSetEx()

// Go from the few obsolete members to their users, instead of scanning every JustMyCode method 5 times
let obsoleteAccessorsAndFields = obsoleteMethods.Cast<IMember>().Concat(obsoleteFields)
   .Concat(obsoleteProperties.SelectMany(x => x.AccessorsAndBackingField).Where(x => x.IsMethod))
   .Concat(obsoleteEvents.SelectMany(x => x.AccessorsAndBackingField).Where(x => x.IsMethod))
let usersOfObsoleteMembers = obsoleteAccessorsAndFields
   .SelectMany(x => x.IsMethod ? x.AsMethod.MethodsCallingMe : x.AsField.MethodsUsingMe)
   .Where(x => JustMyCode.Contains(x))
from m in JustMyCode.Methods.UsingAny(obsoleteTypes).Union(usersOfObsoleteMembers)

let obsoleteTypesUsed = obsoleteTypes.UsedBy(m)

// Optimization: MethodsCalled + Intersect() is faster than using obsoleteMethods.UsedBy()
let obsoleteMethodsUsed = m.MethodsCalled.Intersect(obsoleteMethods)
let obsoleteFieldsUsed = obsoleteFields.UsedBy(m)
let obsoletePropertiesUsed = obsoleteProperties.SelectMany(x => x.AccessorsAndBackingField).UsedBy(m)
let obsoleteEventsUsed = obsoleteEvents.SelectMany(x => x.AccessorsAndBackingField).UsedBy(m)

let obsoleteUsage = obsoleteTypesUsed.Except(m.ParentType).Cast<IMember>()
                    .Concat(obsoleteMethodsUsed)
                    .Concat(obsoleteFieldsUsed)
                    .Concat(obsoletePropertiesUsed)
                    .Concat(obsoleteEventsUsed).ToArray()
where obsoleteUsage.Length > 0

select new {
   m, 
   obsoleteUsage,
   Debt = (5*obsoleteUsage.Count()).ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Expl>
// The *{0}* shouldn't use the *{1}* {1?:all }marked as *obsolete*.
// Removing {1?this usage:these usages} will facilitate smoother transitions to newer versions.
//</Expl>

//<Desc>
// Warns about methods using a type, method or field tagged with
// *System.ObsoleteAttribute*: such API elements will be removed sooner or
// later and shouldn't be used.
//</Desc>

//<HowToFix>
// Follow the *workaround message* typically provided with
// *System.ObsoleteAttribute* to avoid the obsolete element.
//
// Estimated Debt: 5 minutes per type, method or field used. Severity is
// **High**: it is important to no longer rely on obsolete code.
//</HowToFix>

Design: all 16 items