Skip to content

Commit

Permalink
Modify S4050: Promote C# rule to SonarWay (#4135)
Browse files Browse the repository at this point in the history
  • Loading branch information
sebastien-marichal authored Aug 9, 2024
1 parent 78f32ca commit dce07c6
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 41 deletions.
2 changes: 1 addition & 1 deletion rules/S4050/csharp/metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"sqKey": "S4050",
"scope": "All",
"defaultQualityProfiles": [

"Sonar way"
],
"quickfix": "unknown"
}
81 changes: 41 additions & 40 deletions rules/S4050/csharp/rule.adoc
Original file line number Diff line number Diff line change
@@ -1,59 +1,54 @@
== Why is this an issue?

When implementing operator overloads, it is very important to make sure that all related operators and methods are consistent in their implementation.
When overloading some arithmetic operator overloads, it is very important to make sure that all related operators and methods are consistent in their implementation.

The following guidelines should be followed:

* When providing ``++operator ==++`` you should also provide ``++operator !=++`` and vice-versa.
* When providing ``++operator ==++`` you should also provide ``++Equals(Object)++`` and ``++GetHashCode()++``.
* When providing ``++operator +, -, *, / or %++`` you should also provide ``++operator ==++``, respecting previous guidelines.
* When providing `operator ==, !=` you should also provide `Equals(Object)` and `GetHashCode()`.
* When providing `operator +, -, *, / or %` you should also provide `operator ==`, respecting the previous guideline.
This rule raises an issue when any of these guidelines are not followed on publicly-visible type (public, protected or protected internal).
This rule raises an issue when any of these guidelines are not followed on a publicly-visible class or struct (`public`, `protected` or `protected internal`).

== How to fix it

=== Noncompliant code example
Make sure to implement all related operators.

[source,csharp]
----
using System;
=== Code examples

==== Noncompliant code example

namespace MyLibrary
[source,csharp,diff-id=1,diff-type=noncompliant]
----
public class Foo // Noncompliant
{
public class Foo // Noncompliant
{
private int left;
private int right;
public Foo(int l, int r)
{
this.left = l;
this.right = r;
this.left = l;
this.right = r;
}
public static Foo operator +(Foo a, Foo b)
{
return new Foo(a.left + b.left, a.right + b.right);
return new Foo(a.left + b.left, a.right + b.right);
}
public static Foo operator -(Foo a, Foo b)
{
return new Foo(a.left - b.left, a.right - b.right);
return new Foo(a.left - b.left, a.right - b.right);
}
}
}
----


=== Compliant solution
==== Compliant solution

[source,csharp]
[source,csharp,diff-id=1,diff-type=compliant]
----
using System;
namespace MyLibrary
public class Foo
{
public class Foo
{
private int left;
private int right;
Expand All @@ -63,42 +58,48 @@ namespace MyLibrary
this.right = r;
}
public static Foo operator +(Foo a, Foo b)
public override bool Equals(Object obj)
{
return new Foo(a.left + b.left, a.right + b.right);
var a = obj as Foo;
if (a == null)
return false;
return this == a;
}
public static Foo operator -(Foo a, Foo b)
public override int GetHashCode()
{
return new Foo(a.left - b.left, a.right - b.right);
return HashCode.Combine(right, left);
}
public static bool operator ==(Foo a, Foo b)
public static Foo operator +(Foo a, Foo b)
{
return (a.left == b.left && a.right == b.right);
return new Foo(a.left + b.left, a.right + b.right);
}
public static bool operator !=(Foo a, Foo b)
public static Foo operator -(Foo a, Foo b)
{
return !(a == b);
return new Foo(a.left - b.left, a.right - b.right);
}
public override bool Equals(Object obj)
public static bool operator ==(Foo a, Foo b)
{
Foo a = obj as Foo;
if (a == null)
return false;
return this == a;
return a.left == b.left && a.right == b.right;
}
public override int GetHashCode()
public static bool operator !=(Foo a, Foo b)
{
return (this.left * 10) + this.right;
return !(a == b);
}
}
}
----

== Resources
=== Documentation

* Microsoft Learn - https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/operator-overloading[Operator overloading]
* Microsoft Learn - https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/equality-operators[Equality operators]
* Microsoft Learn - https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/arithmetic-operators[Arithmetic operators (C# reference)]

ifdef::env-github,rspecator-view[]

'''
Expand Down

0 comments on commit dce07c6

Please sign in to comment.