2009-08-31 118 views
17

我明白我可以调用ToString()。IndexOf(...),但我不想创建额外的字符串。我明白我可以手动编写搜索例程。我只是想知道为什么这样的例程在框架中不存在。为什么StringBuilder没有IndexOf方法?

回答

5

不幸的是,为String实现的许多方法可能已经为StringBuilder实现,但还没有完成。考虑使用扩展方法来添加你关心的内容。

1

StringBuilder上调用ToString()不会创建额外的对象,令人困惑。在内部,StringBuilder存储一个String对象,用于执行;调用ToString()只是返回该对象。

+0

如果StringBuilder的被要求修改本身Tthen创建一个新的* *字符串这不是问题的情况下是正确的,内部缓冲器的可变性不暴露于托管代码。 – ShuggyCoUk 2009-09-01 00:04:06

+0

@ ShuggyCoUk:我的评论有点过分。我已将其删除。 – 2009-09-01 00:11:15

+10

为了澄清以前的评论,调用ToString没有太多的开销。但是在你调用它之后,StringBuilder的下一个修改将会导致拷贝开销。 (这是一个有效的优化,因为ToString通常是对StringBuilder完成的最后一件事情。)因此,类似String的方法的高效实现不能使用ToString,这样就排除了原始海报问题的简单解决方案。 – 2009-09-01 02:10:23

36

我知道这是一个老问题,但是我写了一个扩展方法,在StringBuilder上执行IndexOf。在下面。我希望它可以帮助任何人发现这个问题,无论是从谷歌搜索或搜索StackOverflow

/// <summary> 
/// Returns the index of the start of the contents in a StringBuilder 
/// </summary>   
/// <param name="value">The string to find</param> 
/// <param name="startIndex">The starting index.</param> 
/// <param name="ignoreCase">if set to <c>true</c> it will ignore case</param> 
/// <returns></returns> 
public static int IndexOf(this StringBuilder sb, string value, int startIndex, bool ignoreCase) 
{    
    int index; 
    int length = value.Length; 
    int maxSearchLength = (sb.Length - length) + 1; 

    if (ignoreCase) 
    { 
     for (int i = startIndex; i < maxSearchLength; ++i) 
     { 
      if (Char.ToLower(sb[i]) == Char.ToLower(value[0])) 
      { 
       index = 1; 
       while ((index < length) && (Char.ToLower(sb[i + index]) == Char.ToLower(value[index]))) 
        ++index; 

       if (index == length) 
        return i; 
      } 
     } 

     return -1; 
    } 

    for (int i = startIndex; i < maxSearchLength; ++i) 
    { 
     if (sb[i] == value[0]) 
     { 
      index = 1; 
      while ((index < length) && (sb[i + index] == value[index])) 
       ++index; 

      if (index == length) 
       return i; 
     } 
    } 

    return -1; 
} 
+1

据说[使用String.ToUpperInvariant方法而不是String.ToLowerInvariant方法,当您规范化字符串进行比较](https://docs.microsoft.com/en-us/dotnet/standard/base-types/best-practices -strings#建议换字符串使用)。我想这对于字符比较也是正确的:[Char.ToUpper和Char.ToLower的工作方式与上一节中介绍的String.ToUpper和String.ToLower方法类似](https://docs.microsoft.com/en-us/dotnet/standard/base-types/best-practices-strings#chartoupper-and-chartolower) – Sergey 2018-02-24 14:28:08

+0

Fair call;随时对上述帖子进行编辑。 – Dennis 2018-02-26 02:11:20

+1

对不起,我错了。实际上微软已经优化了* ToUpperInvariant()*,而不是* ToUpper()*。在这种情况下,默认情况下,我们不能提供* ToUpperInvariant()*,只要它可能导致某些语言(如土耳其语)的错误比较。所以,在这方面,你的代码是绝对正确的。 – Sergey 2018-02-26 10:55:04

相关问题