调用MemoryExtensions.ToUpper时,目标Span长度等于源是否安全?是否存在扩容场景?
MemoryExtensions.ToUpper 目标Span长度安全性及内存占用问题
核心结论
当目标Span长度与源Span完全相同时,并非始终安全,部分字符在特定文化规则下转大写后会占用更多字符位置,导致目标空间不足。同时,调用ToUpper()确实存在转换后字符串需要更多内存的情况。
不安全场景示例
最典型的例子是德语(CultureInfo.GetCultureInfo("de-DE"))中的小写字符ß:
- 源Span内容:
ReadOnlySpan<char> source = "ß";(长度为1) - 若目标Span仅分配1个字符的空间(比如
stackalloc char[1]),调用source.ToUpper(destination, new CultureInfo("de-DE"))时,ß会被转换为SS(长度为2),目标空间不足以容纳结果,方法会返回一个大于目标Span长度的数值,说明转换失败。
内存占用增加的情况说明
除了德语的ß,还有其他文化特定的字符转换会导致长度增加:
- 比如希腊语(
el-GR)中的部分连字字符,转换为大写时会拆分为多个独立字符; - 这类场景下,转换后的字符串长度必然超过原字符串,自然需要更多内存存储。
稳妥的处理方式
如果无法提前确定转换后的长度,建议先调用无目标参数的ToUpper重载获取所需的目标长度,再分配足够空间:
ReadOnlySpan<char> source = "ß"; var culture = new CultureInfo("de-DE"); // 先获取所需长度 int requiredLength = source.ToUpper(culture); // 分配足够的目标Span Span<char> destination = stackalloc char[requiredLength]; // 执行转换 int resultLength = source.ToUpper(destination, culture); // resultLength 会等于 requiredLength,确保转换成功
内容的提问来源于stack exchange,提问作者Petar
相关产品推荐
相关产品推荐

