{"action":"created","issue":{"url":"https://api.github.com/repos/dotnet/corefx/issues/8034","repository_url":"https://api.github.com/repos/dotnet/corefx","labels_url":"https://api.github.com/repos/dotnet/corefx/issues/8034/labels{/name}","comments_url":"https://api.github.com/repos/dotnet/corefx/issues/8034/comments","events_url":"https://api.github.com/repos/dotnet/corefx/issues/8034/events","html_url":"https://github.com/dotnet/corefx/issues/8034","id":150712672,"number":8034,"title":"Adding a HashCode type to help with combining hash codes","user":{"login":"jamesqo","id":9159214,"avatar_url":"https://avatars.githubusercontent.com/u/9159214?v=3","gravatar_id":"","url":"https://api.github.com/users/jamesqo","html_url":"https://github.com/jamesqo","followers_url":"https://api.github.com/users/jamesqo/followers","following_url":"https://api.github.com/users/jamesqo/following{/other_user}","gists_url":"https://api.github.com/users/jamesqo/gists{/gist_id}","starred_url":"https://api.github.com/users/jamesqo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jamesqo/subscriptions","organizations_url":"https://api.github.com/users/jamesqo/orgs","repos_url":"https://api.github.com/users/jamesqo/repos","events_url":"https://api.github.com/users/jamesqo/events{/privacy}","received_events_url":"https://api.github.com/users/jamesqo/received_events","type":"User","site_admin":false},"labels":[{"id":153714228,"url":"https://api.github.com/repos/dotnet/corefx/labels/api-needs-work","name":"api-needs-work","color":"207de5","default":false},{"id":147576314,"url":"https://api.github.com/repos/dotnet/corefx/labels/area-System.Numerics","name":"area-System.Numerics","color":"d4c5f9","default":false},{"id":206504884,"url":"https://api.github.com/repos/dotnet/corefx/labels/Design%20Discussion","name":"Design Discussion","color":"5319e7","default":false},{"id":337781680,"url":"https://api.github.com/repos/dotnet/corefx/labels/netfx-port-consider","name":"netfx-port-consider","color":"5319e7","default":false}],"state":"open","locked":false,"assignee":{"login":"karelz","id":5776068,"avatar_url":"https://avatars.githubusercontent.com/u/5776068?v=3","gravatar_id":"","url":"https://api.github.com/users/karelz","html_url":"https://github.com/karelz","followers_url":"https://api.github.com/users/karelz/followers","following_url":"https://api.github.com/users/karelz/following{/other_user}","gists_url":"https://api.github.com/users/karelz/gists{/gist_id}","starred_url":"https://api.github.com/users/karelz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/karelz/subscriptions","organizations_url":"https://api.github.com/users/karelz/orgs","repos_url":"https://api.github.com/users/karelz/repos","events_url":"https://api.github.com/users/karelz/events{/privacy}","received_events_url":"https://api.github.com/users/karelz/received_events","type":"User","site_admin":false},"assignees":[{"login":"karelz","id":5776068,"avatar_url":"https://avatars.githubusercontent.com/u/5776068?v=3","gravatar_id":"","url":"https://api.github.com/users/karelz","html_url":"https://github.com/karelz","followers_url":"https://api.github.com/users/karelz/followers","following_url":"https://api.github.com/users/karelz/following{/other_user}","gists_url":"https://api.github.com/users/karelz/gists{/gist_id}","starred_url":"https://api.github.com/users/karelz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/karelz/subscriptions","organizations_url":"https://api.github.com/users/karelz/orgs","repos_url":"https://api.github.com/users/karelz/repos","events_url":"https://api.github.com/users/karelz/events{/privacy}","received_events_url":"https://api.github.com/users/karelz/received_events","type":"User","site_admin":false},{"login":"jamesqo","id":9159214,"avatar_url":"https://avatars.githubusercontent.com/u/9159214?v=3","gravatar_id":"","url":"https://api.github.com/users/jamesqo","html_url":"https://github.com/jamesqo","followers_url":"https://api.github.com/users/jamesqo/followers","following_url":"https://api.github.com/users/jamesqo/following{/other_user}","gists_url":"https://api.github.com/users/jamesqo/gists{/gist_id}","starred_url":"https://api.github.com/users/jamesqo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jamesqo/subscriptions","organizations_url":"https://api.github.com/users/jamesqo/orgs","repos_url":"https://api.github.com/users/jamesqo/repos","events_url":"https://api.github.com/users/jamesqo/events{/privacy}","received_events_url":"https://api.github.com/users/jamesqo/received_events","type":"User","site_admin":false}],"milestone":{"url":"https://api.github.com/repos/dotnet/corefx/milestones/5","html_url":"https://github.com/dotnet/corefx/milestones/Future","labels_url":"https://api.github.com/repos/dotnet/corefx/milestones/5/labels","id":1328080,"number":5,"title":"Future","description":"Milestone tracking the issues triaged for an unspecified future release","creator":{"login":"joshfree","id":1302850,"avatar_url":"https://avatars.githubusercontent.com/u/1302850?v=3","gravatar_id":"","url":"https://api.github.com/users/joshfree","html_url":"https://github.com/joshfree","followers_url":"https://api.github.com/users/joshfree/followers","following_url":"https://api.github.com/users/joshfree/following{/other_user}","gists_url":"https://api.github.com/users/joshfree/gists{/gist_id}","starred_url":"https://api.github.com/users/joshfree/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/joshfree/subscriptions","organizations_url":"https://api.github.com/users/joshfree/orgs","repos_url":"https://api.github.com/users/joshfree/repos","events_url":"https://api.github.com/users/joshfree/events{/privacy}","received_events_url":"https://api.github.com/users/joshfree/received_events","type":"User","site_admin":false},"open_issues":652,"closed_issues":426,"state":"open","created_at":"2015-09-29T00:25:45Z","updated_at":"2016-11-29T01:25:12Z","due_on":null,"closed_at":null},"comments":180,"created_at":"2016-04-24T23:21:16Z","updated_at":"2016-11-29T03:18:17Z","closed_at":null,"body":"### Motivation\r\n\r\nJava has `Objects.hash` for quickly combining the hash codes of constituent fields to return in `Object.hashCode()`. Unfortunately, .NET has no such equivalent and developers are forced to roll their own hashes like [this](http://stackoverflow.com/a/263416/4077294):\r\n\r\n``` cs\r\npublic override int GetHashCode()\r\n{\r\n    unchecked\r\n    {\r\n        int result = 17;\r\n        result = result * 23 + field1.GetHashCode();\r\n        result = result * 23 + field2.GetHashCode();\r\n        return result;\r\n    }\r\n}\r\n```\r\n\r\n[Sometimes](https://msdn.microsoft.com/en-us/library/system.object.gethashcode.aspx) people even resort to using `Tuple.Create(field1, field2, ...).GetHashCode()` for this, which is bad (obviously) since it allocates.\r\n\r\n### Proposal\r\n\r\n- List of changes in current proposal (against last approved version https://github.com/dotnet/corefx/issues/8034#issuecomment-262331783):\r\n  - `Empty` property added (as natural starting point analogous to `ImmutableArray`)\r\n  - Argument names updated: `hash`->`hashCode`, `obj` -> `item`\r\n\r\n```cs\r\nnamespace System\r\n{\r\n    public struct HashCode : IEquatable<HashCode>\r\n    {\r\n        public HashCode();\r\n\r\n        public static HashCode Empty { get; }\r\n\r\n        public static HashCode Create(int hashCode);\r\n        public static HashCode Create<T>(T item);\r\n        public static HashCode Create<T>(T item, IEqualityComparer<T> comparer);\r\n\r\n        public HashCode Combine(int hashCode);\r\n        public HashCode Combine<T>(T item);\r\n        public HashCode Combine<T>(T item, IEqualityComparer<T> comparer);\r\n\r\n        public int Value { get; }\r\n\r\n        public static implicit operator int(HashCode hashCode);\r\n\r\n        public static bool operator ==(HashCode left, HashCode right);\r\n        public static bool operator !=(HashCode left, HashCode right);\r\n\r\n        public bool Equals(HashCode other);\r\n        public override bool Equals(object obj);\r\n        public override int GetHashCode();\r\n        public override string ToString();\r\n    }\r\n}\r\n```\r\n\r\nUsage:\r\n\r\n```c#\r\nint hashCode1 = HashCode.Create(f1).Combine(f2).Value;\r\nint hashCode2 = hashes.Aggregate(HashCode.Empty, (seed, hash) => seed.Combine(hash));\r\n\r\nvar hashCode3 = HashCode.Empty;\r\nforeach (int hash in hashes) { hashCode3 = hashCode3.Combine(hash); }\r\n(int)hashCode3;\r\n```\r\n\r\n### Notes\r\n\r\nImplementation should use algorithm in [`HashHelpers`](https://github.com/dotnet/corefx/blob/master/src/Common/src/System/Numerics/Hashing/HashHelpers.cs#L9)."},"comment":{"url":"https://api.github.com/repos/dotnet/corefx/issues/comments/263465281","html_url":"https://github.com/dotnet/corefx/issues/8034#issuecomment-263465281","issue_url":"https://api.github.com/repos/dotnet/corefx/issues/8034","id":263465281,"user":{"login":"terrajobst","id":5169960,"avatar_url":"https://avatars.githubusercontent.com/u/5169960?v=3","gravatar_id":"","url":"https://api.github.com/users/terrajobst","html_url":"https://github.com/terrajobst","followers_url":"https://api.github.com/users/terrajobst/followers","following_url":"https://api.github.com/users/terrajobst/following{/other_user}","gists_url":"https://api.github.com/users/terrajobst/gists{/gist_id}","starred_url":"https://api.github.com/users/terrajobst/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/terrajobst/subscriptions","organizations_url":"https://api.github.com/users/terrajobst/orgs","repos_url":"https://api.github.com/users/terrajobst/repos","events_url":"https://api.github.com/users/terrajobst/events{/privacy}","received_events_url":"https://api.github.com/users/terrajobst/received_events","type":"User","site_admin":false},"created_at":"2016-11-29T03:18:17Z","updated_at":"2016-11-29T03:18:17Z","body":"> Kills the perf - no.\r\n> Performance penalty paid for syntax sugar - yes.\r\n\r\nIt's more than syntactic sugar. If we were willing to make `HashCode` a class, then it would be syntactic sugar. But a mutable value type is a bug farm. \r\n\r\nQuoting you from earlier:\r\n\r\n> It is exactly why it is important for it to be robust. The key value of .NET is that it addresses problems for people who don't know better.\r\n\r\nI'd argue that a mutable value type is not a robust API for the majority of the people who don't know better."}}
{"actor":{"display_login":"terrajobst"}}