120 lines
2.8 KiB
Plaintext
120 lines
2.8 KiB
Plaintext
== Why is this an issue?
|
||
|
||
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 `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 a publicly-visible class or struct (`public`, `protected` or `protected internal`).
|
||
|
||
== How to fix it
|
||
|
||
Make sure to implement all related operators.
|
||
|
||
=== Code examples
|
||
|
||
==== Noncompliant code example
|
||
|
||
[source,csharp,diff-id=1,diff-type=noncompliant]
|
||
----
|
||
public class Foo // Noncompliant
|
||
{
|
||
private int left;
|
||
private int right;
|
||
|
||
public Foo(int l, int 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);
|
||
}
|
||
|
||
public static Foo operator -(Foo a, Foo b)
|
||
{
|
||
return new Foo(a.left - b.left, a.right - b.right);
|
||
}
|
||
}
|
||
----
|
||
|
||
|
||
==== Compliant solution
|
||
|
||
[source,csharp,diff-id=1,diff-type=compliant]
|
||
----
|
||
public class Foo
|
||
{
|
||
private int left;
|
||
private int right;
|
||
|
||
public Foo(int l, int r)
|
||
{
|
||
this.left = l;
|
||
this.right = r;
|
||
}
|
||
|
||
public override bool Equals(Object obj)
|
||
{
|
||
var a = obj as Foo;
|
||
if (a == null)
|
||
return false;
|
||
return this == a;
|
||
}
|
||
|
||
public override int GetHashCode()
|
||
{
|
||
return HashCode.Combine(right, left);
|
||
}
|
||
|
||
public static Foo operator +(Foo a, Foo b)
|
||
{
|
||
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);
|
||
}
|
||
|
||
public static bool operator ==(Foo a, Foo b)
|
||
{
|
||
return a.left == b.left && a.right == b.right;
|
||
}
|
||
|
||
public static bool operator !=(Foo a, Foo b)
|
||
{
|
||
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[]
|
||
|
||
'''
|
||
== Implementation Specification
|
||
(visible only on this page)
|
||
|
||
=== Message
|
||
|
||
Provide an implementation for: {0}.
|
||
|
||
|
||
=== Highlighting
|
||
|
||
Operator + or operator - declaration
|
||
|
||
|
||
endif::env-github,rspecator-view[]
|