字符串长度 vs 字符数组长度。

10
我正在整理一些旧代码,该代码反复执行myString.ToCharArray().Length; 而不是myString.Length
在我重构 ToCharArray() 之前,是否存在任何情况下这样做会导致不同的行为?

我认为很难想象每种可能的情况。这是其中一种需要测试并观察的事情。 - user1477388
@user1477388 我已经查看了一些简单的情况。如果有异常情况,那就是在“有趣”的Unicode行为领域,而不是普通的日常情况。遍历整个字符集以暴力破解几十亿个测试字符串比提问要花费更长的时间。 - Dan Is Fiddling By Firelight
@DanNeely 请参见http://stackoverflow.com/questions/5495523/x-tochararray-length-equals-getbytesx-length - Alex
@voo 因为我没有将任何数据转换成字节码,所以这似乎与问题无关。 - Dan Is Fiddling By Firelight
4个回答

9
没有区别:用反射器查看方法代码,它将根据字符串的长度分配一个char[]。

3
具体来说,ToCharArray() 方法返回的原始字符串和 char[] 数组都是字符串内容的 UTF-16 表示形式。在这两种情况下,长度都是表示文本所需的 UTF-16 代码点的数量,因此它们将匹配。 - Sam Harwell
1
第二个也可能会出现NullReferenceExceptions。 - Oleksandr Fentsyk
4
NullReferenceException 这个提示和任何事情有什么关系?如果字符串是 null,在这两种情况下都会发生这种情况。 - Grant Thomas

3
两者肯定会返回相同的长度,代表字符数(char)。每个索引位置上都会有一个字符(或数组),然后以下内容可能值得一提:

Length 属性返回此实例中 Char 对象的数量,而不是 Unicode 字符的数量。原因是一个 Unicode 字符可能由多个 Char 表示。使用 System.Globalization.StringInfo 类来处理每个 Unicode 字符,而不是每个 Char。

从这里可以推断出,ToCharArray 也是如此,因为它给出了"一个 Unicode 字符数组,其中的元素是此实例的单个字符"
我不确定关于 NullReferenceException 的内容是什么,因为两者也可能受到此影响。

2

会导致不同的行为吗?

好的,像其他人说的一样,在这两种方式中,结果都将是char的数量,所以答案绝对是NO

但我想在这个答案中添加一些不同的东西。

当我反编译String.ToCharArray()方法时,它看起来像:

public unsafe char[] ToCharArray()
{
  int length = this.Length;
  char[] chArray = new char[length];
  if (length > 0)
  {
    fixed (char* smem = &this.m_firstChar)
      fixed (char* dmem = chArray)
        string.wstrcpyPtrAligned(dmem, smem, length);
  }
  return chArray;
}
ToCharArray使用unsafe代码来操作指针,同时还使用了基类库中的私有方法wstrcpyPtrAligned。通常情况下,它比在托管代码中执行同样操作更快,因为托管代码需要检查数组边界。
但是,它需要完全遍历字符串,如果您不需要这样做,手动填充字符数组可能会更快。
由于ToCharArray()方法返回一个char数组,您可以就地修改它。这有时可以提高代码的性能。

我认为这个东西的可变性并不成问题,而且正如你所看到的,ToCharArray方法无论如何都会检查字符串的长度,因此肯定不会有性能提升。 - Grant Thomas

0

我认为在任何情况下它都不会产生不同的结果!

但是,如果我使用它的重载方法,即ToCharArray(int startIndex, int length),那么显然它可以根据你提供的长度给出不同的长度属性值。

此外,我无法像ToString()方法一样在我的自定义类中覆盖ToCharArray()方法。因此,如果您只想计算长度,则使用myString.Length比使用myString.ToCharArray().Length更有意义。


我们不能像ToString()方法那样重写ToCharArray()方法。我将重写ToString()方法在我的类中添加一些额外的逻辑。 - Sanjeev Rai

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接