diff --git a/analyzers/rspec/cs/S1244.html b/analyzers/rspec/cs/S1244.html index 988fa5b667e..ea798821338 100644 --- a/analyzers/rspec/cs/S1244.html +++ b/analyzers/rspec/cs/S1244.html @@ -20,7 +20,7 @@
float myNumber = 3.146f; -if (myNumber == 3.146f) //Noncompliant: due to floating point imprecision, this will likely be false +if (myNumber == 3.146f) // Noncompliant: due to floating point imprecision, this will likely be false { // ... } diff --git a/analyzers/rspec/cs/S1694.html b/analyzers/rspec/cs/S1694.html index 544f8565a6a..e65e24d82bb 100644 --- a/analyzers/rspec/cs/S1694.html +++ b/analyzers/rspec/cs/S1694.html @@ -1,23 +1,31 @@ +A
class
with onlyabstract
methods and no inheritable behavior should be converted to aninterface
.Why is this an issue?
-The purpose of an abstract class is to provide some heritable behaviors while also defining methods which must be implemented by sub-classes.
-A
-class
with onlyabstract
methods and no inheritable behavior should be converted to aninterface
.Noncompliant code example
+The purpose of an
+abstract
+class is to provide some overridable behaviors while also defining methods that are required to be implemented by sub-classes.A class that contains only
+abstract
methods, often called pure abstract class, is effectively an interface, but with the disadvantage +of not being able to be implemented by multiple classes.Using interfaces over pure abstract classes presents multiple advantages:
+
abstract
classes that contain non-abstract methods, in addition to abstract
ones, cannot easily be converted to
+interfaces, and are not the subject of this rule:
-public abstract class Animal // Noncompliant; should be an interface -{ - abstract void Move(); - abstract void Feed(); -} --
-public interface Animal -{ - void Move(); - void Feed(); -} - -public abstract class Lamp +public abstract class Lamp // Compliant: Glow is abstract, but FlipSwitch is not { private bool switchLamp = false; @@ -33,4 +41,49 @@+Compliant solution
} }
Notice that, since C# 8.0, you can also define default implementations for +interface methods, which is yet another reason to prefer interfaces over abstract classes when you don’t need to provide any inheritable +behavior.
+However, interfaces cannot have fields (such as switchLamp
in the example above), and that remains true even in C# 8.0 and upwards.
+This can be a valid reason to still prefer an abstract class over an interface.
Convert the abstract
class to an interface
with the same methods.
+public abstract class Animal // Noncompliant: should be an interface +{ + public abstract void Move(); + public abstract void Feed(); +} ++
+public interface Animal +{ + void Move(); + void Feed(); +} ++
Command
, Message
, or Event
are ignored as messaging libraries often use
- them. Command
, Message
, Event
, or Query
are ignored as messaging
+ libraries often use them. System.Exception
are ignored; even an empty Exception class can provide helpful information by its type name alone.
System.Attribute
and classes annotated with attributes are ignored. diff --git a/analyzers/rspec/cs/S3264.html b/analyzers/rspec/cs/S3264.html index 6c9f850a2b2..9a700662311 100644 --- a/analyzers/rspec/cs/S3264.html +++ b/analyzers/rspec/cs/S3264.html @@ -4,11 +4,11 @@Noncompliant code example
class UninvokedEventSample { - private event Action<object, EventArgs> Happened; //Noncompliant + private event Action<object, EventArgs> Happened; // Noncompliant public void RegisterEventHandler(Action<object, EventArgs> handler) { - Happened += handler; //we register some event handlers + Happened += handler; // we register some event handlers } public void RaiseEvent() diff --git a/analyzers/rspec/cs/S5344.html b/analyzers/rspec/cs/S5344.html index 93a8273649c..92f26b5f26a 100644 --- a/analyzers/rspec/cs/S5344.html +++ b/analyzers/rspec/cs/S5344.html @@ -135,7 +135,7 @@Compliant solution
RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider(); byte[] salt = new byte[32]; rngCsp.GetBytes(salt); -Rfc2898DeriveBytes kdf = new Rfc2898DeriveBytes(password, salt, 100_000, HashAlgorithmName.SHA256); // Noncompliant +Rfc2898DeriveBytes kdf = new Rfc2898DeriveBytes(password, salt, 100_000, HashAlgorithmName.SHA256); // Compliant string hashed = Convert.ToBase64String(kdf.GetBytes(256 / 8));How does this work?
diff --git a/analyzers/rspec/cs/S6962.html b/analyzers/rspec/cs/S6962.html index a0c92ad10ce..4dd23b0704a 100644 --- a/analyzers/rspec/cs/S6962.html +++ b/analyzers/rspec/cs/S6962.html @@ -39,7 +39,7 @@Noncompliant code example
[HttpGet] public async Task<string> Foo() { - using var client = new HttpClient(); //Noncompliant + using var client = new HttpClient(); // Noncompliant return await client.GetStringAsync(_url); } } diff --git a/analyzers/rspec/cs/S6962.json b/analyzers/rspec/cs/S6962.json index 7f75bbd5f10..b9d25981bd2 100644 --- a/analyzers/rspec/cs/S6962.json +++ b/analyzers/rspec/cs/S6962.json @@ -6,7 +6,9 @@ "func": "Constant\/Issue", "constantCost": "1h" }, - "tags": [], + "tags": [ + "asp.net" + ], "defaultSeverity": "Major", "ruleSpecification": "RSPEC-6962", "sqKey": "S6962", diff --git a/analyzers/rspec/vbnet/S2094.html b/analyzers/rspec/vbnet/S2094.html index 236aebc03a8..27f9f629b79 100644 --- a/analyzers/rspec/vbnet/S2094.html +++ b/analyzers/rspec/vbnet/S2094.html @@ -17,8 +17,8 @@Compliant solution
Exceptions
Command
, Message
, or Event
are ignored as messaging libraries often use
- them. Command
, Message
, Event
, or Query
are ignored as messaging
+ libraries often use them. System.Exception
are ignored; even an empty Exception class can provide helpful information by its type name alone.
System.Attribute
and classes annotated with attributes are ignored. ElementAt
.NET 7.0
15,193.1 ns
233.47 ns
3,403.4 ns
28.52 ns
26.67 ns
Index
.NET 7.0
9,465.6 ns
148.16 ns
478.0 ns
6.93 ns
6.48 ns
First
.NET 7.0
7,790.2 ns
165.70 ns
6,160.0 ns
57.66 ns
53.93 ns
First_Index
.NET 7.0
398.5 ns
5.36 ns
485.7 ns
5.81 ns
5.15 ns
Last
.NET 7.0
7,398.2 ns
152.48 ns
6,034.3 ns
20.34 ns
16.98 ns
Last_Index
.NET 7.0
347.3 ns
5.47 ns
ElementAt
.NET Framework 4.6.2
12,205.7 ns
298.49 ns
Index
.NET Framework 4.6.2
8,917.8 ns
51.55 ns
First
.NET Framework 4.6.2
5,109.1 ns
100.13 ns
First_Index
.NET Framework 4.6.2
566.0 ns
6.56 ns
Last
.NET Framework 4.6.2
5,052.7 ns
76.02 ns
Last_Index
.NET Framework 4.6.2
680.7 ns
9.56 ns
408.3 ns
2.54 ns
2.38 ns
Hardware configuration:
-BenchmarkDotNet=v0.13.5, OS=Windows 10 (10.0.19045.2846/22H2/2022Update) +BenchmarkDotNet=v0.13.5, OS=Windows 10 (10.0.19045.4412/22H2/2022Update) 11th Gen Intel Core i7-11850H 2.50GHz, 1 CPU, 16 logical and 8 physical cores -.NET SDK=7.0.203 - [Host] : .NET 7.0.5 (7.0.523.17405), X64 RyuJIT AVX2 - .NET 7.0 : .NET 7.0.5 (7.0.523.17405), X64 RyuJIT AVX2 - .NET Framework 4.6.2 : .NET Framework 4.8.1 (4.8.9139.0), X64 RyuJIT VectorSize=256 +.NET SDK=8.0.301 + [Host] : .NET 8.0.6 (8.0.624.26715), X64 RyuJIT AVX2 + .NET 8.0 : .NET 8.0.6 (8.0.624.26715), X64 RyuJIT AVX2diff --git a/analyzers/src/SonarAnalyzer.CSharp/sonarpedia.json b/analyzers/src/SonarAnalyzer.CSharp/sonarpedia.json index b1751e8bbb0..6df42c584f5 100644 --- a/analyzers/src/SonarAnalyzer.CSharp/sonarpedia.json +++ b/analyzers/src/SonarAnalyzer.CSharp/sonarpedia.json @@ -3,7 +3,7 @@ "languages": [ "CSH" ], - "latest-update": "2024-06-05T08:43:15.694332900Z", + "latest-update": "2024-06-10T14:50:07.301026900Z", "options": { "no-language-in-filenames": true } diff --git a/analyzers/src/SonarAnalyzer.VisualBasic/sonarpedia.json b/analyzers/src/SonarAnalyzer.VisualBasic/sonarpedia.json index 85c38152c2d..6e293fd822d 100644 --- a/analyzers/src/SonarAnalyzer.VisualBasic/sonarpedia.json +++ b/analyzers/src/SonarAnalyzer.VisualBasic/sonarpedia.json @@ -3,7 +3,7 @@ "languages": [ "VBNET" ], - "latest-update": "2024-05-31T08:11:17.885759100Z", + "latest-update": "2024-06-10T14:50:28.179058600Z", "options": { "no-language-in-filenames": true }