如何不调用.ToString()将十六进制ReadOnlySpan<char>转为Int32
十六进制ReadOnlySpan转int(无内存分配解决方案)
推荐方案:使用.NET内置Span重载
从.NET Core 2.1、.NET 5+开始,Int32.Parse提供了直接接收ReadOnlySpan<char>的重载,无需调用ToString(),完全消除额外内存分配:
preParse = Int32.Parse(chars, NumberStyles.AllowHexSpecifier);
直接替换原代码中Int32.Parse(chars.ToString(), ...)即可,内置实现经过优化,能可靠处理十六进制解析的边界情况,是最简洁高效的选择。
兼容旧框架方案:手动实现无分配解析
如果项目基于不支持Span重载的旧框架(如.NET Framework),可以手动实现正确的十六进制解析逻辑——你之前的循环逻辑错误,正确的方式是每次将当前值左移4位(等价于乘以16),再累加当前字符对应的十六进制数值:
int ParseHexSpan(ReadOnlySpan<char> hexSpan) { int result = 0; foreach (char c in hexSpan) { result <<= 4; if (c >= '0' && c <= '9') { result += c - '0'; } else if (c >= 'A' && c <= 'F') { result += c - 'A' + 10; } else if (c >= 'a' && c <= 'f') { result += c - 'a' + 10; } else { throw new FormatException($"无效十六进制字符: {c}"); } } return result; }
调用时直接用preParse = ParseHexSpan(chars);,无任何内存分配,且能正确解析(比如104D130会转为17092912)。
优化后的完整代码
替换ToString()调用后,你的代码可修改为:
List<int> offsetsList = new List<int>(); int x = 0; foreach (ReadOnlySpan<char> chars in address.SplitWithSpan()) { if (address.Contains("base") && x == 0) { x += 1; continue; } int preParse = Int32.Parse(chars, NumberStyles.AllowHexSpecifier); offsetsList.Add(preParse); offsetsList.Add(preParse); }
内容的提问来源于stack exchange,提问作者PassionateStudent
相关产品推荐
相关产品推荐

