Use RuntimeHelpers.GetHashCode instead of obj.GetHashCode (#31756)
authorRoman Marusyk <Marusyk@users.noreply.github.com>
Thu, 6 Feb 2020 05:31:05 +0000 (07:31 +0200)
committerGitHub <noreply@github.com>
Thu, 6 Feb 2020 05:31:05 +0000 (21:31 -0800)
* Use RuntimeHelpers.GetHashCode instead of obj.GetHashCode

* Fix unit test

* Code review fixes

* Code review fixes

* Update src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReferenceEqualsEqualityComparer.cs

Co-Authored-By: David Cantu <jozkyy@gmail.com>
Co-authored-by: David Cantu <jozkyy@gmail.com>
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReferenceEqualsEqualityComparer.cs
src/libraries/System.Text.Json/tests/Serialization/ReferenceHandlingTests.Serialize.cs

index 9fd6ece..6f3667c 100644 (file)
@@ -3,6 +3,7 @@
 // See the LICENSE file in the project root for more information.
 
 using System.Collections.Generic;
+using System.Runtime.CompilerServices;
 
 namespace System.Text.Json.Serialization
 {
@@ -21,7 +22,7 @@ namespace System.Text.Json.Serialization
 
         int IEqualityComparer<T>.GetHashCode(T obj)
         {
-            return obj!.GetHashCode();
+            return RuntimeHelpers.GetHashCode(obj!);
         }
     }
 }
index ab09f3c..4271db9 100644 (file)
@@ -217,12 +217,12 @@ namespace System.Text.Json.Serialization.Tests
             };
 
             string json = JsonSerializer.Serialize(list, s_serializerOptionsPreserve);
-            Assert.Equal(@"{""$id"":""1"",""$values"":[{""$id"":""2""},{""$id"":""3""}]}", json);
+            Assert.Equal(@"{""$id"":""1"",""$values"":[{""$id"":""2""},{""$ref"":""2""}]}", json);
 
             List<ClassIncorrectHashCode> listCopy = JsonSerializer.Deserialize<List<ClassIncorrectHashCode>>(json, s_serializerOptionsPreserve);
-            // When a GetHashCode method is implemented incorrectly, round-tripping breaks,
-            // that is a user error and this validates that we are always calling user's GetHashCode.
-            Assert.NotSame(listCopy[0], listCopy[1]);
+            // Make sure that our DefaultReferenceResolver calls the ReferenceEqualityComparer that implements RuntimeHelpers.GetHashCode, and never object.GetHashCode,
+            // otherwise objects would not be correctly identified when searching for them in the dictionary.
+            Assert.Same(listCopy[0], listCopy[1]);
         }
     }
 }