Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
| Property | Value | 
|---|---|
| Rule ID | CA1501 | 
| Title | Avoid excessive inheritance | 
| Category | Maintainability | 
| Fix is breaking or non-breaking | Breaking | 
| Default threshold | 5 | 
| Enabled by default in .NET 9 | No | 
Cause
A type is five or more levels deep in its inheritance hierarchy.
Rule description
Deeply nested type hierarchies can be difficult to follow, understand, and maintain. This rule limits analysis to hierarchies in the same module.
You can configure this rule in the following ways:
- By default, the rule excludes types from the Systemnamespace. You can configure the rule to exclude other types or namespaces as well.
- You can configure the inheritance tree depth at which this rule fires.
How to fix violations
To fix a violation of this rule, derive the type from a base type that is less deep in the inheritance hierarchy or eliminate some of the intermediate base types.
When to suppress warnings
It's safe to suppress a warning from this rule. However, the code might be more difficult to maintain. Depending on the visibility of base types, resolving violations of this rule might create breaking changes. For example, removing public base types is a breaking change.
Note
You might see false positive warnings from this rule if all of the following apply:
- You're using Visual Studio 2022 version 17.5 or later with an older version of the .NET SDK, that is, .NET 6 or earlier.
- You're using the analyzers from the .NET 6 SDK or an older version of the analyzer packages, such as Microsoft.CodeAnalysis.FxCopAnalyzers.
The false positives are due to a breaking change in the C# compiler. Consider using a newer analyzer that contains the fix for the false positive warnings. Upgrade to Microsoft.CodeAnalysis.NetAnalyzers version 7.0.0-preview1.22464.1 or newer or use the analyzers from the .NET 7 SDK.
Suppress a warning
If you just want to suppress a single violation, add preprocessor directives to your source file to disable and then re-enable the rule.
#pragma warning disable CA1501
// The code that's violating the rule is on this line.
#pragma warning restore CA1501
To disable the rule for a file, folder, or project, set its severity to none in the configuration file.
[*.{cs,vb}]
dotnet_diagnostic.CA1501.severity = none
For more information, see How to suppress code analysis warnings.
Configure threshold
You can configure the threshold at which this rule fires.
- Create a text file named CodeMetricsConfig.txt. 
- Add the desired threshold to the text file in the following format: - CA1501: 8- In this example, the rule is configured to fire when a type is eight or more levels deep in its inheritance hierarchy. 
- In the project file, mark the build action of the configuration file as AdditionalFiles. For example: - <ItemGroup> <AdditionalFiles Include="CodeMetricsConfig.txt" /> </ItemGroup>
Configure code to analyze
Use the following option to configure which parts of your codebase to run this rule on.
You can configure this option for just this rule, for all rules it applies to, or for all rules in this category (Maintainability) that it applies to. For more information, see Code quality rule configuration options.
Inheritance excluded type or namespace names
You can configure the rule to exclude certain types or namespaces from the inheritance hierarchy tree. By default, all types from the System.* namespace are excluded. No matter what value you set, this default value is added.
| Option Value | Summary | 
|---|---|
| dotnet_code_quality.CA1501.additional_inheritance_excluded_symbol_names = MyType | Matches all types named MyTypeor whose containing namespace containsMyType(and all types from theSystemnamespace) | 
| dotnet_code_quality.CA1501.additional_inheritance_excluded_symbol_names = MyType1|MyType2 | Matches all types named either MyType1orMyType2or whose containing namespace contains eitherMyType1orMyType2(and all types from theSystemnamespace) | 
| dotnet_code_quality.CA1501.additional_inheritance_excluded_symbol_names = T:NS.MyType | Matches specific type MyTypein the namespaceNS(and all types from theSystemnamespace) | 
| dotnet_code_quality.CA1501.additional_inheritance_excluded_symbol_names = T:NS1.MyType1|T:NS2.MyType2 | Matches specific types MyType1andMyType2with respective fully qualified names (and all types from theSystemnamespace) | 
| dotnet_code_quality.CA1501.additional_inheritance_excluded_symbol_names = N:NS | Matches all types from the NSnamespace (and all types from theSystemnamespace) | 
| dotnet_code_quality.CA1501.additional_inheritance_excluded_symbol_names = My* | Matches all types whose name starts with Myor whose containing namespace parts starts withMy(and all types from theSystemnamespace) | 
| dotnet_code_quality.CA1501.additional_inheritance_excluded_symbol_names = T:NS.My* | Matches all types whose name starts with Myin the namespaceNS(and all types from theSystemnamespace) | 
| dotnet_code_quality.CA1501.additional_inheritance_excluded_symbol_names = N:My* | Matches all types whose containing namespace starts with My(and all types from theSystemnamespace) | 
Example
The following example shows a type that violates the rule:
class BaseClass {}
class FirstDerivedClass : BaseClass {}
class SecondDerivedClass : FirstDerivedClass {}
class ThirdDerivedClass : SecondDerivedClass {}
class FourthDerivedClass : ThirdDerivedClass {}
// This class violates the rule.
class FifthDerivedClass : FourthDerivedClass {}
Imports System
Namespace ca1501
    Class BaseClass
    End Class
    Class FirstDerivedClass
        Inherits BaseClass
    End Class
    Class SecondDerivedClass
        Inherits FirstDerivedClass
    End Class
    Class ThirdDerivedClass
        Inherits SecondDerivedClass
    End Class
    Class FourthDerivedClass
        Inherits ThirdDerivedClass
    End Class
    ' This class violates the rule.
    Class FifthDerivedClass
        Inherits FourthDerivedClass
    End Class
End Namespace