{"action":"created","issue":{"url":"https://api.github.com/repos/dotnet/corefx/issues/14904","repository_url":"https://api.github.com/repos/dotnet/corefx","labels_url":"https://api.github.com/repos/dotnet/corefx/issues/14904/labels{/name}","comments_url":"https://api.github.com/repos/dotnet/corefx/issues/14904/comments","events_url":"https://api.github.com/repos/dotnet/corefx/issues/14904/events","html_url":"https://github.com/dotnet/corefx/issues/14904","id":199042762,"number":14904,"title":"Possible type equality bug using generics and the `==` operator after deserialization.","user":{"login":"Carl-Hugo","id":5885505,"avatar_url":"https://avatars.githubusercontent.com/u/5885505?v=3","gravatar_id":"","url":"https://api.github.com/users/Carl-Hugo","html_url":"https://github.com/Carl-Hugo","followers_url":"https://api.github.com/users/Carl-Hugo/followers","following_url":"https://api.github.com/users/Carl-Hugo/following{/other_user}","gists_url":"https://api.github.com/users/Carl-Hugo/gists{/gist_id}","starred_url":"https://api.github.com/users/Carl-Hugo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Carl-Hugo/subscriptions","organizations_url":"https://api.github.com/users/Carl-Hugo/orgs","repos_url":"https://api.github.com/users/Carl-Hugo/repos","events_url":"https://api.github.com/users/Carl-Hugo/events{/privacy}","received_events_url":"https://api.github.com/users/Carl-Hugo/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":12,"created_at":"2017-01-05T19:48:26Z","updated_at":"2017-01-06T18:01:31Z","closed_at":"2017-01-05T23:01:22Z","body":"### Title\r\nPossible type equality bug using generics and the `==` operator after deserialization.\r\n\r\n### Scenario\r\nI was implementing an `IEqualityComparer<T>` to simplify my life, and all my tests worked fine until I compared a deserialized version of the same objects.\r\n\r\n### Functional impact\r\nThe `==` operator does not behave the same after deserialization as when no serialization is involved.\r\n\r\nThe comparison of two values using the `==` operator should be the same with or without serialization involved (consistency).\r\n\r\n### Minimal repro steps\r\nI created a full repro project here, including a workaround (under `MyClassEqualityComparer.AlternateEquals(...)`): \r\nhttps://github.com/Carl-Hugo/ReproGenericEqualityNetCoreBug\r\n\r\n*Please note that, for simplicity sake, `MyClassEqualityComparer` does not implement `IEqualityComparer<T>` since it was not needed.*\r\n\r\nThe minimal repro steps are:\r\n```CSharp\r\nnamespace ReproProject\r\n{\r\n    public class MyClass<T>\r\n        where T : class\r\n    {\r\n        public MyClass() { }\r\n\r\n        public MyClass(T value)\r\n        {\r\n            Value = value;\r\n        }\r\n\r\n        public virtual T Value { get; set; }\r\n    }\r\n\r\n    public class MyClassEqualityComparer<T>\r\n        where T : class\r\n    {\r\n        public bool Equals(MyClass<T> x, MyClass<T> y)\r\n        {\r\n            var sameValue = x.Value == y.Value;\r\n            return sameValue;\r\n        }\r\n    }\r\n    public class Program\r\n    {\r\n        private static MyClassEqualityComparer<string> Comparer { get; } = new MyClassEqualityComparer<string>();\r\n\r\n        public static void Main(string[] args)\r\n        {\r\n            var object1 = new MyClass<string>(\"My value 1\");\r\n            var object2 = new MyClass<string>(\"My value 1\");\r\n\r\n            var serializedObject1 = JsonConvert.SerializeObject(object1);\r\n            var serializedObject2 = JsonConvert.SerializeObject(object2);\r\n\r\n            var deserializedObject1 = JsonConvert.DeserializeObject<MyClass<string>>(serializedObject1);\r\n            var deserializedObject2 = JsonConvert.DeserializeObject<MyClass<string>>(serializedObject2);\r\n\r\n            var valuesAreEquals = Comparer.Equals(deserializedObject1, deserializedObject2); // this should be true since `\"My value 1\" == \"My value 1\"`\r\n            Console.WriteLine($\"Values ({deserializedObject1.Value}|{deserializedObject2.Value}), with serialization, should be equals: {valuesAreEquals}\");\r\n            Console.Read();\r\n        }\r\n    }\r\n}\r\n```\r\n\r\n### Expected result\r\nThe method call `Comparer.Equals(...)` should return `true` since `\"My value 1\" == \"My value 1\"`, compared by the following: `x.Value == y.Value`.\r\n\r\n### Actual result\r\nThe result is `false`.\r\n\r\n### Conclusion\r\nI hope this is the right place; it is a bit hard to figure out to what repo a general issue should be posted to.\r\n\r\nIf it is not, feel free to point me the right way :)"},"comment":{"url":"https://api.github.com/repos/dotnet/corefx/issues/comments/270963761","html_url":"https://github.com/dotnet/corefx/issues/14904#issuecomment-270963761","issue_url":"https://api.github.com/repos/dotnet/corefx/issues/14904","id":270963761,"user":{"login":"jnm2","id":8040367,"avatar_url":"https://avatars.githubusercontent.com/u/8040367?v=3","gravatar_id":"","url":"https://api.github.com/users/jnm2","html_url":"https://github.com/jnm2","followers_url":"https://api.github.com/users/jnm2/followers","following_url":"https://api.github.com/users/jnm2/following{/other_user}","gists_url":"https://api.github.com/users/jnm2/gists{/gist_id}","starred_url":"https://api.github.com/users/jnm2/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jnm2/subscriptions","organizations_url":"https://api.github.com/users/jnm2/orgs","repos_url":"https://api.github.com/users/jnm2/repos","events_url":"https://api.github.com/users/jnm2/events{/privacy}","received_events_url":"https://api.github.com/users/jnm2/received_events","type":"User","site_admin":false},"created_at":"2017-01-06T18:01:31Z","updated_at":"2017-01-06T18:01:31Z","body":"@JonHanna what slack channel? (I came across yet another example in [`HashSet<>.HashSetEquals`](https://github.com/dotnet/corefx/blob/master/src/System.Collections/src/System/Collections/Generic/HashSet.cs#L1636).)"}}
{"actor":{"display_login":"jnm2"}}