You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[API Proposal] add ReadOnlySpan<byte> overloads to BitConverter.ToString() #50588
BitConverter.ToString() has no overloads to accept Readonlyspan. When we got a span we have to call ToArray() first. Other BitConverter functions do have a Readonlyspan overload, such as BitConverter.ToInt32().
Proposed API
namespace System
{
public class BitConverter {
+ public static string ToString(ReadOnlySpan<byte> value);
}
FYI we don't normally add startIndex and length parameters on APIs which take spans. The caller is expected to slice the span appropriately before calling the method.
Do you have a usage example where you're relying on BitConverter.ToString in your own code? The example you provided won't compile, even with the APIs you had proposed here.
Yes I do have but I cannot show it public. However I can show you a variation of it:
constintinfoLength=32;byte[]infoStartingBytes={0xFF,0xFF,0xFF,0xFF};ReadOnlySpan<byte>span=System.IO.File.ReadAllBytes("C:\\data.dat").AsSpan();intpos=span.IndexOf(infoStartingBytes);while(pos!=-1){span=span.Slice(span.IndexOf(infoStartingBytes));intid=BitConverter.ToInt32(span);span=span.Slice(infoLength+1);stringname=System.Text.Encoding.UTF8.GetString(span);span=span.Slice(infoLength+1);// couple of lines laterstringhash=BitConverter.ToString(span.Slice(infoLength).ToArray());span=span.Slice(infoLength+1);// saving these information somewherepos=span.IndexOf(infoStartingBytes);}
Using a span has the benefit of slicing. However at one point I have to convert it back to an array when I want to use BitConverter.ToString. I wouldn't mind if there is no overload with startIndex and length parameters since this can easily applied to the span instead but I want to get rid of the additional extra allocation of ToArray(). And I asked myself why every other function of BitConverter has received a span overload but not ToString?
Just want to point out that the details of the format used, dashes or not, casing, etc. was debated at length in #17837, and the decision then was to just add Convert.ToHexString that only offered the one approach of no separators, all upper-case.
I'm not suggesting changing behavior. Convert.ToHexString already takes a span and produces a hex string, just without dashes. I was questioning whether we need another.
I'm not suggesting changing behavior. Convert.ToHexString already takes a span and produces a hex string, just without dashes. I was questioning whether we need another.
So, all of us that do require the dash* have to either change our logic (not just code), roll our own hex formatter or keep allocating (and copying) memory on the heap? Don't get me wrong, all 3 are fair, its not like our existing code got broken...
I agree that #17837 is a better forward solution, I will probably end up changing my code to use it instead myself.
If no overload is added, perhaps BitConverter.ToString should be decorated with [Obsolete("Use Convert.ToHexString where possible")] so developers that remove the '-' easily realize they don't have to anymore =].
*I personally kept the dash because didn't want the performance hit of removing them.
I'm not suggesting changing behavior. Convert.ToHexString already takes a span and produces a hex string, just without dashes. I was questioning whether we need another.
Well in my use case, I use the BitConverter.ToString method to print the hex string to the console for debug purposes. Having dashes keeps the string more readable for me. I often have to write some thing along this just for debugging:
As per the above, this was already debated extensively in a past API review and we opted to not go this route. There's not enough interest in this specific API and the overwhelming majority are using the APIs on Convert instead which don't involve any separator. Users who really need this and who cannot just use the existing byte[] value, int startIndex, int length overload can always copy the 20-30 lines of code required.
Activity
GrabYourPitchforks commentedon Apr 1, 2021
FYI we don't normally add startIndex and length parameters on APIs which take spans. The caller is expected to slice the span appropriately before calling the method.
Do you have a usage example where you're relying on
BitConverter.ToStringin your own code? The example you provided won't compile, even with the APIs you had proposed here.Symbai commentedon Apr 1, 2021
Yes I do have but I cannot show it public. However I can show you a variation of it:
Using a span has the benefit of slicing. However at one point I have to convert it back to an array when I want to use BitConverter.ToString. I wouldn't mind if there is no overload with startIndex and length parameters since this can easily applied to the span instead but I want to get rid of the additional extra allocation of ToArray(). And I asked myself why every other function of BitConverter has received a span overload but not ToString?
GrabYourPitchforks commentedon Apr 1, 2021
Thanks! I'll mark this ready for review.
stephentoub commentedon Apr 1, 2021
Having the dashes between each byte is important to your use case?
stephentoub commentedon Apr 1, 2021
Just want to point out that the details of the format used, dashes or not, casing, etc. was debated at length in #17837, and the decision then was to just add Convert.ToHexString that only offered the one approach of no separators, all upper-case.
1 remaining item
stephentoub commentedon Apr 2, 2021
I'm not suggesting changing behavior. Convert.ToHexString already takes a span and produces a hex string, just without dashes. I was questioning whether we need another.
XArtur0 commentedon Jun 17, 2021
So, all of us that do require the dash* have to either change our logic (not just code), roll our own hex formatter or keep allocating (and copying) memory on the heap? Don't get me wrong, all 3 are fair, its not like our existing code got broken...
I agree that #17837 is a better forward solution, I will probably end up changing my code to use it instead myself.
If no overload is added, perhaps
BitConverter.ToStringshould be decorated with[Obsolete("Use Convert.ToHexString where possible")]so developers that remove the '-' easily realize they don't have to anymore =].*I personally kept the dash because didn't want the performance hit of removing them.
msschl commentedon Aug 25, 2021
Well in my use case, I use the
BitConverter.ToStringmethod to print the hex string to the console for debug purposes. Having dashes keeps the string more readable for me. I often have to write some thing along this just for debugging:where
reader.ReadBytes(numOfBytes)returns aReadOnlySpan<byte>I personally would appreciate adding this api.
Symbai commentedon Feb 28, 2026
Comment
tannergooding commentedon Apr 3, 2026
Closing this as not planned.
As per the above, this was already debated extensively in a past API review and we opted to not go this route. There's not enough interest in this specific API and the overwhelming majority are using the APIs on
Convertinstead which don't involve any separator. Users who really need this and who cannot just use the existingbyte[] value, int startIndex, int lengthoverload can always copy the 20-30 lines of code required.