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 lowercase support for Convert.ToHexString #60393
But HexConverter is an internal class, and the case transforming in HexConverter.ToString is faster than calling String.ToUpper() again, because HexConverter use ssse3 or bit operations.
Add a new method will be simple because the internal class has supported it already.
I wonder if Convert.ToHexStringLower would be better. The Casing enum is more of an internal implementation detail to make a few internal things "easier" and shouldn't be publicly exposed.
bool might be another option, but given we probably shouldn't ever have more than just Upper and Lower here so it might not be necessary.
Instead of a bool or casing enum maybe this should be improved further solving other cases as well, see #50588 Then we could get rid of all at once, instead of creating APIs for every use case, just me 2 cents?!
Instead of a bool or casing enum maybe this should be improved further solving other cases as well, see #50588 Then we could get rid of all at once, instead of creating APIs for every use case, just me 2 cents?!
The original contributed api was more complicated, but in the end they were simplified. See #17837 (comment) . However, casing is already supported in the fundamentals.
I wonder if Convert.ToHexStringLower would be better. The Casing enum is more of an internal implementation detail to make a few internal things "easier" and shouldn't be publicly exposed.
bool might be another option, but given we probably shouldn't ever have more than just Upper and Lower here so it might not be necessary.
I personally prefer bool. After all it's really strange if there is no Convert.ToHexStringUpper along with Convert.ToHexStringLower.
Sorry for intrusion but I'd like to strongly support this issue. When implementing an API for some of the internal libraries at my current workplace, there was no option to either specify the casing or supply a mutable buffer to Convert.ToHexString(input) which forces the chaining of ToLowerInvariant() without an option to avoid allocating an output string twice. The library API itself is using bool flag to specify the case but it could've as well been either an enum or bitmask enum options if a more advanced customisation was deemed necessary.
@neon-sunset When Convert.ToHexString was approved there was a video discussion. Lower case was part of the API proposal but the .NET team decided to not take it. The argument was that its actually just a one liner and that they will keep it short and simple first as they tend to over engineer APIs. Also regarding your enum this was explicit denied outside of the video but within the API proposal thread.
@neon-sunset When Convert.ToHexString was approved there was a video discussion. Lower case was part of the API proposal but the .NET team decided to not take it. The argument was that its actually just a one liner and that they will keep it short and simple first as they tend to over engineer APIs. Also regarding your enum this was explicit denied outside of the video but within the API proposal thread.
It's not convincing because an optional argument can keep it simple too. Plus, it's a confusing fact that runtime internals can take the advantage of the faster HexConverter.ToString, but app developers need an additional convert which is absolutely slower than the former. The inefficiency can turn into a trouble problem in web apps, finally a more hack, user-implemented method is needed to replace the runtime API method. I'm now using code fragments form tkp1n/HexMate, and it can be fast and more aggressively vectorized. The .NET team should really reconsider the problem.
Reacted by Richard Collette, Paulus Pärssinen, Ian Qvist, NilFusion and LeaFrock
@tannergooding do you think this should go to API review? Perhaps with your simple proposal. There's considerable upvotes so it seems like there's a real need for something more efficient than post processing the casing.
We discussed it, and rather than adding an enum (or bool), we feel that the parallel method group with the "Lower" suffix is better, even if slightly unbalanced.
On the issue of supporting dashes, once we can .TryToHexStringLower() to a destination span, it'd be pretty easy to pre-allocate a larger span and shuffle the output around to achieve any required formatting, which would also require no allocation. I have personally never needed dashes but very frequently need lowercase hex. MAC addresses are one common scenario for dashes but the PhysicalAddress class already handles that.
Also it seems like the decision has been made, but HexFormattingOptions would have been substantially cleaner. It aligns with .ToBase64CharArray() and .ToBase64String()'s Base64FormattingOptions (which also only has a single option in it), and wouldn't add an entire extra method that also doesn't match the original method (.ToHexString() should have been called .ToHexStringUpper()).
Reacted by Roman Bukin, Fabian König, Cédric Luthi and cocowalla
The lockdown of runtime API is in August. The approval of this issue is after the lockdown of .NET 8. In fact, it's the very first approvals of .NET 9.
Activity
tannergooding commentedon Oct 14, 2021
I wonder if
Convert.ToHexStringLowerwould be better. TheCasingenum is more of an internal implementation detail to make a few internal things "easier" and shouldn't be publicly exposed.boolmight be another option, but given we probably shouldn't ever have more than justUpperandLowerhere so it might not be necessary.Symbai commentedon Oct 14, 2021
Instead of a
boolorcasingenum maybe this should be improved further solving other cases as well, see #50588 Then we could get rid of all at once, instead of creating APIs for every use case, just me 2 cents?!determ1ne commentedon Oct 15, 2021
The original contributed api was more complicated, but in the end they were simplified. See #17837 (comment) . However,
casingis already supported in the fundamentals.determ1ne commentedon Oct 15, 2021
I personally prefer
bool. After all it's really strange if there is noConvert.ToHexStringUpperalong withConvert.ToHexStringLower.neon-sunset commentedon Nov 29, 2021
Sorry for intrusion but I'd like to strongly support this issue. When implementing an API for some of the internal libraries at my current workplace, there was no option to either specify the casing or supply a mutable buffer to
Convert.ToHexString(input)which forces the chaining ofToLowerInvariant()without an option to avoid allocating an output string twice. The library API itself is usingboolflag to specify the case but it could've as well been either anenumor bitmask enum options if a more advanced customisation was deemed necessary.Symbai commentedon Nov 29, 2021
@neon-sunset When Convert.ToHexString was approved there was a video discussion. Lower case was part of the API proposal but the .NET team decided to not take it. The argument was that its actually just a one liner and that they will keep it short and simple first as they tend to over engineer APIs. Also regarding your enum this was explicit denied outside of the video but within the API proposal thread.
determ1ne commentedon Dec 2, 2021
It's not convincing because an optional argument can keep it simple too. Plus, it's a confusing fact that runtime internals can take the advantage of the faster
HexConverter.ToString, but app developers need an additional convert which is absolutely slower than the former. The inefficiency can turn into a trouble problem in web apps, finally a more hack, user-implemented method is needed to replace the runtime API method. I'm now using code fragments form tkp1n/HexMate, and it can be fast and more aggressively vectorized. The .NET team should really reconsider the problem.rcollette commentedon Jan 13, 2022
After watching the video (https://www.youtube.com/watch?v=H3obznO9_uo&t=2528s) The options flag seems like the next step.
Genbox commentedon Jun 26, 2022
In case anyone is interested, here are the benchmark results between .NET 6 and HexMate:

It clearly shows that HexMate with the
HexFormattingOptions.Lowercaseflag is much faster than usingToLowerInvariant().Source code:
danmoseley commentedon Jun 26, 2022
@tannergooding do you think this should go to API review? Perhaps with your simple proposal. There's considerable upvotes so it seems like there's a real need for something more efficient than post processing the casing.
15 remaining items
bartonjs commentedon Sep 21, 2023
Video
We discussed it, and rather than adding an enum (or bool), we feel that the parallel method group with the "Lower" suffix is better, even if slightly unbalanced.
tannergooding commentedon Sep 22, 2023
Marked
help wanted. Please let me know if you'd like to pick this up and contribute the new API surface.determ1ne commentedon Sep 22, 2023
Please take a look at #92483
tomrus88 commentedon Sep 23, 2023
Can't believe that such a simple thing requires over 2 years to be added...
crozone commentedon Sep 23, 2023
On the issue of supporting dashes, once we can
.TryToHexStringLower()to a destination span, it'd be pretty easy to pre-allocate a larger span and shuffle the output around to achieve any required formatting, which would also require no allocation. I have personally never needed dashes but very frequently need lowercase hex. MAC addresses are one common scenario for dashes but thePhysicalAddressclass already handles that.crozone commentedon Sep 23, 2023
Also it seems like the decision has been made, but
HexFormattingOptionswould have been substantially cleaner. It aligns with.ToBase64CharArray()and.ToBase64String()'sBase64FormattingOptions(which also only has a single option in it), and wouldn't add an entire extra method that also doesn't match the original method (.ToHexString()should have been called.ToHexStringUpper()).LeaFrock commentedon Nov 20, 2023
Just to confirm: is this API going to be released after .NET 9 rather than 8?
Have to wait for another one year 😅 .
huoyaoyuan commentedon Nov 20, 2023
The lockdown of runtime API is in August. The approval of this issue is after the lockdown of .NET 8. In fact, it's the very first approvals of .NET 9.