{"action":"created","issue":{"url":"https://api.github.com/repos/dotnet/corefx/issues/1514","labels_url":"https://api.github.com/repos/dotnet/corefx/issues/1514/labels{/name}","comments_url":"https://api.github.com/repos/dotnet/corefx/issues/1514/comments","events_url":"https://api.github.com/repos/dotnet/corefx/issues/1514/events","html_url":"https://github.com/dotnet/corefx/issues/1514","id":70825767,"number":1514,"title":"Add String.Format overloads to avoid unnecessary allocations","user":{"login":"justinvp","id":710598,"avatar_url":"https://avatars.githubusercontent.com/u/710598?v=3","gravatar_id":"","url":"https://api.github.com/users/justinvp","html_url":"https://github.com/justinvp","followers_url":"https://api.github.com/users/justinvp/followers","following_url":"https://api.github.com/users/justinvp/following{/other_user}","gists_url":"https://api.github.com/users/justinvp/gists{/gist_id}","starred_url":"https://api.github.com/users/justinvp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/justinvp/subscriptions","organizations_url":"https://api.github.com/users/justinvp/orgs","repos_url":"https://api.github.com/users/justinvp/repos","events_url":"https://api.github.com/users/justinvp/events{/privacy}","received_events_url":"https://api.github.com/users/justinvp/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":10,"created_at":"2015-04-25T00:01:53Z","updated_at":"2015-05-27T01:31:02Z","closed_at":null,"body":"It's pretty common to pass value types to `String.Format`, unfortunately this results in unnecessary boxing allocations.\r\n\r\n## Rationale\r\n\r\nConsider the following:\r\n\r\n```c#\r\nlong id = ...;\r\nint index = ...;\r\nint length = ...;\r\n\r\n// Traditional call to String.Format\r\nstring foo = string.Format(\"{0}: Index = {1}, Length = {2}\", id, index, length);\r\n\r\n// Use of the string interpolation language feature\r\nstring bar = $\"{id}: Index = {index}, Length = {length}\";\r\n```\r\n\r\nBoth the traditional call to `String.Format` and the use of the string interpolation language feature (which is just syntactic sugar for `String.Format`) requires 3 boxing allocations.\r\n\r\n## Proposed API\r\n\r\n```c#\r\nnamespace System\r\n{\r\n    public sealed class String : ...\r\n    {\r\n        // Proposed methods\r\n        public static string Format<T0>(string format, T0 arg0);\r\n        public static string Format<T0, T1>(string format, T0 arg0, T1 arg1);\r\n        public static string Format<T0, T1, T2>(string format, T0 arg0, T1 arg1, T2 arg2);\r\n        public static string Format<T0>(IFormatProvider provider, string format, T0 arg0);\r\n        public static string Format<T0, T1>(IFormatProvider provider, string format, T0 arg0, T1 arg1);\r\n        public static string Format<T0, T1, T2>(IFormatProvider provider, string format, T0 arg0, T1 arg1, T2 arg2);\r\n    \r\n        // Existing methods\r\n        public static string Format(string format, object arg0);\r\n        public static string Format(string format, object arg0, object arg1);\r\n        public static string Format(string format, object arg0, object arg1, object arg2);\r\n        public static string Format(string format, params object[] args);\r\n        public static string Format(IFormatProvider provider, string format, object arg0);\r\n        public static string Format(IFormatProvider provider, string format, object arg0, object arg1);\r\n        public static string Format(IFormatProvider provider, string format, object arg0, object arg1, object arg2);\r\n        public static string Format(IFormatProvider provider, string format, params object[] args);\r\n        \r\n        ...\r\n    }\r\n}\r\n\r\nnamespace System.Text\r\n{\r\n    public sealed class StringBuilder\r\n    {\r\n        // Proposed methods\r\n        public StringBuilder AppendFormat<T0>(string format, T0 arg0);\r\n        public StringBuilder AppendFormat<T0, T1>(string format, T0 arg0, T1 arg1);\r\n        public StringBuilder AppendFormat<T0, T1, T2>(string format, T0 arg0, T1 arg1, T2 arg2);\r\n        public StringBuilder AppendFormat<T0>(IFormatProvider provider, string format, T0 arg0);\r\n        public StringBuilder AppendFormat<T0, T1>(IFormatProvider provider, string format, T0 arg0, T1 arg1);\r\n        public StringBuilder AppendFormat<T0, T1, T2>(IFormatProvider provider, string format, T0 arg0, T1 arg1, T2 arg2);\r\n    \r\n        // Existing methods\r\n        public StringBuilder AppendFormat(string format, object arg0);\r\n        public StringBuilder AppendFormat(string format, object arg0, object arg1);\r\n        public StringBuilder AppendFormat(string format, object arg0, object arg1, object arg2);\r\n        public StringBuilder AppendFormat(string format, params object[] args);\r\n        public StringBuilder AppendFormat(IFormatProvider provider, string format, object arg0);\r\n        public StringBuilder AppendFormat(IFormatProvider provider, string format, object arg0, object arg1);\r\n        public StringBuilder AppendFormat(IFormatProvider provider, string format, object arg0, object arg1, object arg2);\r\n        public StringBuilder AppendFormat(IFormatProvider provider, string format, params object[] args);\r\n        \r\n        ...\r\n    }\r\n}\r\n\r\nnamespace System.Runtime.CompilerServices\r\n{\r\n    public static class FormattableStringFactory\r\n    {\r\n        // Proposed methods\r\n        public static FormattableString Create<T0>(string format, T0 argument0);\r\n        public static FormattableString Create<T0, T1>(string format, T0 argument0, T1 argument1);\r\n        public static FormattableString Create<T0, T1, T2>(string format, T0 argument0, T1 argument1, T2 argument2);\r\n        \r\n        // Existing method\r\n        public static FormattableString Create(string format, params object[] arguments);\r\n    }\r\n}\r\n```\r\n\r\nI'd be happy to contribute an implementation and tests."},"comment":{"url":"https://api.github.com/repos/dotnet/corefx/issues/comments/105713390","html_url":"https://github.com/dotnet/corefx/issues/1514#issuecomment-105713390","issue_url":"https://api.github.com/repos/dotnet/corefx/issues/1514","id":105713390,"user":{"login":"MikePopoloski","id":702179,"avatar_url":"https://avatars.githubusercontent.com/u/702179?v=3","gravatar_id":"","url":"https://api.github.com/users/MikePopoloski","html_url":"https://github.com/MikePopoloski","followers_url":"https://api.github.com/users/MikePopoloski/followers","following_url":"https://api.github.com/users/MikePopoloski/following{/other_user}","gists_url":"https://api.github.com/users/MikePopoloski/gists{/gist_id}","starred_url":"https://api.github.com/users/MikePopoloski/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/MikePopoloski/subscriptions","organizations_url":"https://api.github.com/users/MikePopoloski/orgs","repos_url":"https://api.github.com/users/MikePopoloski/repos","events_url":"https://api.github.com/users/MikePopoloski/events{/privacy}","received_events_url":"https://api.github.com/users/MikePopoloski/received_events","type":"User","site_admin":false},"created_at":"2015-05-27T01:31:02Z","updated_at":"2015-05-27T01:31:02Z","body":"Shameless plug of my own work: https://github.com/MikePopoloski/StringFormatter\r\nMight be useful to mine for ideas.\r\n\r\nI too needed string formatting without allocations. It'd be nice to take advantage of some of that dedicated code built into the CLR to make it faster, but it does alright on its own as pure C#."}}