org.sonar.plugins.csharp.S3260.html Maven / Gradle / Ivy
Why is this an issue?
Classes and records with either private
or file
access modifiers aren’t visible outside of their assemblies or files, so
if they’re not extended inside their scope, they should be made explicitly non-extensible with the addition of the sealed
keyword.
What is the potential impact?
We measured at least 4x improvement in execution time. For more details see the Benchmarks
section from the More info
tab.
How to fix it
The code can be improved by adding the sealed
keyword in front of the class
or record
types that have no
inheritors.
Code examples
Noncompliant code example
private class MyClass // Noncompliant
{
// ...
}
private record MyRecord // Noncompliant
{
// ...
}
file class MyClass // Noncompliant
{
// ...
}
file record MyRecord // Noncompliant
{
// ...
}
Compliant solution
private sealed class MyClass
{
// ...
}
private sealed record MyRecord
{
// ...
}
file sealed class MyClass
{
// ...
}
file sealed record MyRecord
{
// ...
}
Resources
Documentation
Articles & blog posts
Benchmarks
Method
Runtime
Mean
Standard Deviation
UnsealedType
.NET 5.0
918.7 us
10.72 us
SealedType
.NET 5.0
231.2 us
3.20 us
UnsealedType
.NET 6.0
867.9 us
5.65 us
SealedType
.NET 6.0
218.4 us
0.59 us
UnsealedType
.NET 7.0
1,074.5 us
3.15 us
SealedType
.NET 7.0
216.1 us
1.19 us
Glossary
The results were generated by running the following snippet with BenchmarkDotNet:
[Params(1_000_000)]
public int Iterations { get; set; }
private readonly UnsealedClass unsealedType = new UnsealedClass();
private readonly SealedClass sealedType = new SealedClass();
[Benchmark(Baseline = true)]
public void UnsealedType()
{
for (int i = 0; i < Iterations; i++)
{
unsealedType.DoNothing();
}
}
[Benchmark]
public void SealedType()
{
for (int i = 0; i < Iterations; i++)
{
sealedType.DoNothing();
}
}
private class BaseType
{
public virtual void DoNothing() { }
}
private class UnsealedClass : BaseType
{
public override void DoNothing() { }
}
private sealed class SealedClass : BaseType
{
public override void DoNothing() { }
}
Hardware Configuration:
BenchmarkDotNet=v0.13.5, OS=Windows 10 (10.0.19045.2846/22H2/2022Update)
12th Gen Intel Core i7-12800H, 1 CPU, 20 logical and 14 physical cores
.NET SDK=7.0.203
[Host] : .NET 7.0.5 (7.0.523.17405), X64 RyuJIT AVX2
.NET 5.0 : .NET 5.0.17 (5.0.1722.21314), X64 RyuJIT AVX2
.NET 6.0 : .NET 6.0.16 (6.0.1623.17311), X64 RyuJIT AVX2
.NET 7.0 : .NET 7.0.5 (7.0.523.17405), X64 RyuJIT AVX2