== Why is this an issue? In C#, the https://learn.microsoft.com/en-us/dotnet/api/system.object.referenceequals[`Object.ReferenceEquals`] method is used to compare two https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/reference-types[reference type] variables. If you use this method to compare two https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/value-types[value types], such as `int`, `float`, or `bool` you will not get the expected results because value type variables contain an instance of the type and not a reference to it. Due to value type variables containing directly an instance of the type, they can't have the same reference, and using `Object.ReferenceEquals` to compare them will always return `false` even if the compared variables have the same value. == How to fix it When comparing value types, prefer using the https://learn.microsoft.com/en-us/dotnet/api/system.object.equals[`Object.Equals`]. Note that in the case of https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/struct[structure types], it is recommended to https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/statements-expressions-operators/how-to-define-value-equality-for-a-type#struct-example[implement value equality]. If not, S3898 might raise. === Code examples ==== Noncompliant code example [source,csharp,diff-id=1,diff-type=noncompliant] ---- using System; struct MyStruct { int valueA; int valueB; } static class MyClass { public static void Method(MyStruct struct1, MyStruct struct2) { if (Object.ReferenceEquals(struct1, struct2)) // Noncompliant: this will be always false { // ... } } } ---- ==== Compliant solution [source,csharp,diff-id=1,diff-type=compliant] ---- using System; struct MyStruct : IEquatable { int valueA; int valueB; public bool Equals(MyStruct other) => valueA == other.valueA && valueB == other.valueB; public override bool Equals(object obj) => obj is MyStruct other && Equals(other); public override int GetHashCode() => HashCode.Combine(valueA, valueB); public static bool operator ==(MyStruct lhs, MyStruct rhs) => lhs.Equals(rhs); public static bool operator !=(MyStruct lhs, MyStruct rhs) => !(lhs == rhs); } static class MyClass { public static void Method(MyStruct struct1, MyStruct struct2) { if (struct1.Equals(struct2)) // Compliant: value are compared { // ... } } } ---- == Resources === Documentation * Microsoft Learn - https://learn.microsoft.com/en-us/dotnet/api/system.object.referenceequals[`Object.ReferenceEquals(Object, Object)` Method] * Microsoft Learn - https://learn.microsoft.com/en-us/dotnet/api/system.object.equals[`Object.Equals` Method] * Microsoft Learn - https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/value-types[Value types (C# reference)] * Microsoft Learn - https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/reference-types[Reference types (C# reference)] * Microsoft Learn - https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/equality-operators[Equality operators - test if two objects are equal or not] * Microsoft Learn - https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/statements-expressions-operators/how-to-define-value-equality-for-a-type#struct-example[How to define value equality for a class or struct (C# Programming Guide)] * Microsoft Learn - https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/struct[Structure types (C# reference)] * S3898 - Value types should implement "IEquatable" ifdef::env-github,rspecator-view[] ''' == Implementation Specification (visible only on this page) === Message Use a different kind of comparison for these value types. ''' == Comments And Links (visible only on this page) === on 3 Jun 2015, 15:56:16 Ann Campbell wrote: \[~tamas.vajk] I'm a little confused about whether it should be `Object...` or `object...`. I followed your lead, but am a little uncomfortable about the inconsistency in usage between title and code sample === on 8 Jun 2015, 09:32:21 Tamas Vajk wrote: LGTM, I've changed the `object` to `Object` just to conform to the title, but there is no difference, because `object` is just an alias for `System.Object` endif::env-github,rspecator-view[]