2009-08-31 10 views

Respuesta

5

Desafortunadamente, muchos de los métodos implementados para String podrían haberse implementado para StringBuilder pero eso no se hizo. Considere usar métodos de extensión para agregar lo que le importa.

1

Llamar a ToString() en un StringBuilder no crea un objeto extra, confusamente. Internamente, StringBuilder almacena un objeto String para el rendimiento; llamando al ToString() simplemente devuelve ese objeto.

+0

esto no es correcto en el contexto de la pregunta si se le pide al StringBuilder modificar en sí Tthen se crea una nueva cadena * *, la mutabilidad del búfer interno no está expuesto al código administrado. – ShuggyCoUk

+0

@ ShuggyCoUk: mi comentario fue un poco simplista. Lo he eliminado –

+10

Para aclarar el comentario anterior, no hay mucha sobrecarga al llamar a ToString. Pero después de llamarlo, la próxima modificación de StringBuilder incurrirá en gastos generales de copia. (Esta es una optimización válida porque ToString suele ser lo último que se le hace a StringBuilder). Como resultado de esto, las implementaciones eficientes de métodos tipo String no pueden usar ToString, lo que impide una solución trivial al problema del cartel original. –

36

Sé que esta es una pregunta anterior, sin embargo, he escrito un método de extensión que realiza un IndexOf en un StringBuilder. Está abajo. Espero que ayude a cualquiera que encuentre esta pregunta, ya sea desde Google buscando o buscando 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

Se dice [Use el método String.ToUpperInvariant en lugar del método String.ToLowerInvariant cuando normaliza cadenas para comparación] (https://docs.microsoft.com/en-us/dotnet/standard/base-types/best-practices -strings # recommendations-for-string-usage). Supongo que esto también es cierto para la comparación de caracteres: [Char.ToUpper y Char.ToLower funcionan de forma similar a los métodos String.ToUpper y String.ToLower descritos en la sección anterior] (https://docs.microsoft.com/es-es/)/dotnet/standard/base-types/best-practices-strings # chartoupper-and-chartolower) – Sergey

+0

Llamada justa; no dude en hacer las ediciones en la publicación anterior. – Dennis

+1

Lo siento, estaba equivocado. En realidad, Microsoft ha optimizado * ToUpperInvariant() *, not * ToUpper() *. En este caso, no podemos proporcionar * ToUpperInvariant() * de forma predeterminada en la medida en que puede dar lugar a una comparación incorrecta en algunos idiomas como el turco. Entonces, en este sentido, tu código es absolutamente correcto. – Sergey

Cuestiones relacionadas