{"action":"created","issue":{"url":"https://api.github.com/repos/dotnet/corefx/issues/31302","repository_url":"https://api.github.com/repos/dotnet/corefx","labels_url":"https://api.github.com/repos/dotnet/corefx/issues/31302/labels{/name}","comments_url":"https://api.github.com/repos/dotnet/corefx/issues/31302/comments","events_url":"https://api.github.com/repos/dotnet/corefx/issues/31302/events","html_url":"https://github.com/dotnet/corefx/issues/31302","id":343881502,"node_id":"MDU6SXNzdWUzNDM4ODE1MDI=","number":31302,"title":"Add span-based overloads of String.GetHashCode","user":{"login":"GrabYourPitchforks","id":1746272,"node_id":"MDQ6VXNlcjE3NDYyNzI=","avatar_url":"https://avatars0.githubusercontent.com/u/1746272?v=4","gravatar_id":"","url":"https://api.github.com/users/GrabYourPitchforks","html_url":"https://github.com/GrabYourPitchforks","followers_url":"https://api.github.com/users/GrabYourPitchforks/followers","following_url":"https://api.github.com/users/GrabYourPitchforks/following{/other_user}","gists_url":"https://api.github.com/users/GrabYourPitchforks/gists{/gist_id}","starred_url":"https://api.github.com/users/GrabYourPitchforks/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/GrabYourPitchforks/subscriptions","organizations_url":"https://api.github.com/users/GrabYourPitchforks/orgs","repos_url":"https://api.github.com/users/GrabYourPitchforks/repos","events_url":"https://api.github.com/users/GrabYourPitchforks/events{/privacy}","received_events_url":"https://api.github.com/users/GrabYourPitchforks/received_events","type":"User","site_admin":false},"labels":[{"id":165998434,"node_id":"MDU6TGFiZWwxNjU5OTg0MzQ=","url":"https://api.github.com/repos/dotnet/corefx/labels/api-ready-for-review","name":"api-ready-for-review","color":"5319e7","default":false},{"id":174276033,"node_id":"MDU6TGFiZWwxNzQyNzYwMzM=","url":"https://api.github.com/repos/dotnet/corefx/labels/area-System.Runtime","name":"area-System.Runtime","color":"d4c5f9","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":3,"created_at":"2018-07-24T04:35:59Z","updated_at":"2018-07-24T20:46:10Z","closed_at":null,"author_association":"MEMBER","body":"ASP.NET has specialized data structures that use span equivalents as keys in dictionaries. As such, they need an equivalent of `String.GetHashCode` which takes `ReadOnlySpan<char>` instead of `string`. I propose the following APIs to enable this scenario.\r\n\r\n```cs\r\nnamespace System {\r\n    public class String {\r\n        // new static APIs on existing string type\r\n        public static int GetHashCode(ReadOnlySpan<char> value);\r\n        public static int GetHashCode(ReadOnlySpan<char> value, StringComparison comparisonType);\r\n    }\r\n}\r\n\r\nnamespace System.Globalization {\r\n    public class CompareInfo {\r\n        // new instance APIs on existing CompareInfo type\r\n        public int GetHashCode(ReadOnlySpan<char> source, CompareOptions options);\r\n    }\r\n}\r\n```\r\n\r\nThe new static APIs on `string` mimic the behaviors of the instance methods `String.GetHashCode()` and `String.GetHashCode(StringComparison)`, respectively. Per previous email discussions we do not want to specialize `ReadOnlySpan<T>.GetHashCode` when `T = char`, and we cannot add this as an extension method, so the next best logical place would be to put this on the `string` type directly.\r\n\r\nThe new instance API on `CompareInfo` mimics the behavior of the existing instance method `CompareInfo.GetHashCode(String, CompareOptions)`. Even though all the other methods on `CompareInfo` are virtual, per last week's API review we determined that there's no legal way for anybody to subclass this type, so new APIs on this type needn't be virtual.\r\n\r\n/cc @rynowak "},"comment":{"url":"https://api.github.com/repos/dotnet/corefx/issues/comments/407546234","html_url":"https://github.com/dotnet/corefx/issues/31302#issuecomment-407546234","issue_url":"https://api.github.com/repos/dotnet/corefx/issues/31302","id":407546234,"node_id":"MDEyOklzc3VlQ29tbWVudDQwNzU0NjIzNA==","user":{"login":"rynowak","id":1430011,"node_id":"MDQ6VXNlcjE0MzAwMTE=","avatar_url":"https://avatars1.githubusercontent.com/u/1430011?v=4","gravatar_id":"","url":"https://api.github.com/users/rynowak","html_url":"https://github.com/rynowak","followers_url":"https://api.github.com/users/rynowak/followers","following_url":"https://api.github.com/users/rynowak/following{/other_user}","gists_url":"https://api.github.com/users/rynowak/gists{/gist_id}","starred_url":"https://api.github.com/users/rynowak/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rynowak/subscriptions","organizations_url":"https://api.github.com/users/rynowak/orgs","repos_url":"https://api.github.com/users/rynowak/repos","events_url":"https://api.github.com/users/rynowak/events{/privacy}","received_events_url":"https://api.github.com/users/rynowak/received_events","type":"User","site_admin":false},"created_at":"2018-07-24T20:46:10Z","updated_at":"2018-07-24T20:46:10Z","author_association":"NONE","body":"Sure, our primary use case for this right now is inside routing. We are executing a state machine and need to make some kind of branching decision based on a section of the URL path. We'd really prefer to do this without the need to substring since most of the time we won't use that content as a string anyway.\r\n\r\nSo we're likely to end up owning our own hash table implementation that stores a set of strings as keys, but can use a `ReadOnlySpan<char>` to look up the value, which in our case is the next state.\r\n\r\nThe hash code part of this is something we don't want to duplicate from CoreCLR because it's pretty general-purpose."}}
{"actor":{"display_login":"rynowak"}}