调用 .ToUpper() 时新字符串是否可能需要更多内存?

Pet*_*tar 36 c# string

我想在 MemoryExtensions 命名空间中使用以下函数

public static int ToUpper(this ReadOnlySpan<char> source, Span<char> destination, CultureInfo? culture)
Run Code Online (Sandbox Code Playgroud)

我现在的问题是:当目标 Span 的长度与源 Span 的长度相同时,我是否总是安全的?例如

destination = stackalloc char[source.Length];
Run Code Online (Sandbox Code Playgroud)

如果不是,有人可以提供一个示例,当在(包括哪种文化)中调用 ToUpper 时,该字符串会转换为更大的字符串吗?

Cha*_*ace 36

MemoryExtensions.ToUpper回报-1如果目的地太小则

\n

源代码ToUpper这个 gem:

\n
// Assuming that changing case does not affect length\nif (destination.Length < source.Length)\n    return -1;\n
Run Code Online (Sandbox Code Playgroud)\n

没有其他地方可以-1返回点,函数以return source.Length;

\n

所以他们认为这不可能发生。他们是否正确是另一个问题:如果你找到反例,我建议你在 GitHub 上提交错误报告。

\n

文档TextInfo(稍后在代码中使用)说:

\n
\n

返回的字符串的长度可能与输入字符串不同。有关大小写的更多信息,请参阅 Unicode 联盟 ( https://www.unicode.org/ )发布的 Unicode 技术报告 #21“大小写映射” 。当前的实现保留了字符串的长度。但是,这种行为并不能得到保证,并且可能在未来的实现中发生变化。

\n
\n
\n

为了进一步澄清,我们讨论的是 UTF-16 中的代码点。我们没有考虑 UTF-8 或 UTF-32,因为char严格来说是 UTF-16。

\n

Unicode 定义大小写映射如下:

\n
\n
    \n
  • 简单(单字符)案例映射

    \n

    ICU 中的一般病例映射是非基于语言的,是 1 对 1 的通用字符映射。

    \n

    如果 Unicode 字符数据库 (UnicodeData.txt) 中为某个字符指定了相应的 \xe2\x80\x9csimple\xe2\x80\x9d 大小写映射,则该字符被视为具有小写、大写或标题大小写等效项。如果字符没有对应的映射,则结果是字符本身。

    \n

    为一般大小写映射提供的 API(位于 uchar.h 文件中)仅处理 UChar32 类型的单个字符并仅返回单个字符。要将字符串转换为非基于语言的特定情况,请使用带有 NULL 参数区域设置的 unistr.h 或 ustring.h 文件中的 API。

    \n
  • \n
  • 完整(特定语言)案例映射

    \n

    不同的区域设置有不同的大小写映射。例如,与英语不同,土耳其语中的字符拉丁小写字母 \xe2\x80\x98i\xe2\x80\x99 具有等效的拉丁大写字母 \xe2\x80\x98I\xe2\x80\x99,上面有点 ( \\u0130 \xe2\x80\x98\xc4\xb0\xe2\x80\x99)。

    \n

    与简单大小写映射 API 类似,如果 Unicode 字符数据库 (UnicodeData.txt) 中为字符指定了相应的映射,则该字符被视为具有小写、大写或标题大小写等效项。在字符没有映射等效项的情况下,结果是字符本身。

    \n

    要将字符串转换为基于特定情况的语言,请使用 ustring.h 和 unistr.h 中的 API 以及预期的参数区域设置。

    \n

    ICU 实现完整的 Unicode 字符串大小写映射。

    \n

    一般来说:

    \n
      \n
    • 大小写映射可以更改字符串的代码点和/或代码单元的数量,
    • \n
    • 是语言敏感的(结果可能因语言而异),并且
    • \n
    • 是上下文相关的(输入字符串中的字符可能会根据周围的字符进行不同的映射)。
    • \n
    \n
  • \n
\n
\n

TL;博士;

\n

理论上,代码点的数量可能会改变(这与字节数是分开的)。但.NET 目前还没有实现这一点。这可能会在没有通知的情况下发生变化,但由于Span.

\n

  • 什么[文档](https://learn.microsoft.com/en-us/dotnet/api/system.globalization.textinfo.toupper?view=net-7.0#system-globalization-textinfo-toupper(system-string) )说: *返回的字符串可能与输入字符串的长度不同。有关大小写的更多信息,请参阅 Unicode 联盟 (https://www.unicode.org) 发布的 Unicode 技术报告 #21“大小写映射”。当前的实现保留了字符串的长度。然而,这种行为并不能得到保证,并且可能在未来的实现中发生变化。* (2认同)
  • 确实如此,但我认为那时必须有一个新的 API 表面来返回所需的长度,因为有很多地方都做出了这种假设。甚至没有这样的函数私下埋藏在“TextInfo”和相关类中。 (2认同)