Обязательно ли проверять перед заменой строки в StringBuilder (используя такие функции, как «Contains» или «IndexOf»)? - PullRequest
13 голосов
/ 21 июня 2011

Есть ли какой-либо метод IndexOf или содержится в C #. Ниже приведен код:

var sb = new StringBuilder(mystring);
sb.Replace("abc", "a");
string dateFormatString = sb.ToString();

if (sb.ToString().Contains("def"))
{
    sb.Replace("def", "aa");
}


if (sb.ToString().Contains("ghi"))
{
    sb.Replace("ghi", "assd");
}

Как вы могли заметить, я снова и снова использую ToString (), чего я хочу избегать, поскольку он создает новую строку каждый раз. Можете ли вы помочь мне, как я могу избежать этого?

Ответы [ 4 ]

19 голосов
/ 21 июня 2011

Если StringBuilder не не содержит "def", то замена не вызовет никаких проблем, поэтому просто используйте:

var sb = new StringBuilder(mystring);
sb.Replace("abc", "a");
sb.Replace("def", "aa");
sb.Replace("ghi", "assd");
5 голосов
/ 21 июня 2011

В StringBuilder такого метода нет, но вам не нужны тесты Contains.Вы можете просто написать это так:

 sb.Replace("abc", "a");
 sb.Replace("def", "aa");
 sb.Replace("ghi", "assd");

Если строка в первом параметре Replace не найдена, то вызов Replace является пустой операцией - именно то, что вы хотите.

Документация гласит:

Заменяет все вхождения указанной строки в этом экземпляре на другую указанную строку.

То, как вы это читаете, заключается в том, что когданет событий, ничего не сделано.

3 голосов
/ 14 октября 2013

Вы можете написать класс, расширяющий методы для объекта StringBuilder.Здесь я добавил IndexOf, Substring и другие методы в класс StringBuilder.Просто поместите этот класс в свой проект.

using System;
using System.Text;

namespace Helpers
{
    /// <summary>
    /// Adds IndexOf, IsStringAt, AreEqual, and Substring to all StringBuilder objects.
    /// </summary>
    public static class StringBuilderExtension
    {
        // Adds IndexOf, Substring, AreEqual to the StringBuilder class.
        public static int IndexOf(this StringBuilder theStringBuilder,string value)
        {
            const int NOT_FOUND = -1;
            if (theStringBuilder == null)
            {
                return NOT_FOUND;
            }
            if (String.IsNullOrEmpty(value))
            {
                return NOT_FOUND;
            }
            int count = theStringBuilder.Length;
            int len = value.Length;            
            if (count < len)
            {
                return NOT_FOUND;
            }
            int loopEnd = count - len + 1;
            for (int loop = 0; loop < loopEnd; loop++)
            {
                bool found = true;
                for (int innerLoop = 0; innerLoop < len; innerLoop++)
                {
                    if (theStringBuilder[loop + innerLoop] != value[innerLoop])
                    {
                        found = false;
                        break;
                    }
                }
                if (found)
                {
                    return loop;
                }
            }
            return NOT_FOUND;
        }
        public static int IndexOf(this StringBuilder theStringBuilder, string value,int startPosition)
        {
            const int NOT_FOUND = -1;
            if (theStringBuilder == null)
            {
                return NOT_FOUND;
            }
            if (String.IsNullOrEmpty(value))
            {
                return NOT_FOUND;
            }
            int count = theStringBuilder.Length;
            int len = value.Length;
            if (count < len)
            {
                return NOT_FOUND;
            }
            int loopEnd = count - len + 1;
            if (startPosition >= loopEnd)
            {
                return NOT_FOUND;
            }
            for (int loop = startPosition; loop < loopEnd; loop++)
            {
                bool found = true;
                for (int innerLoop = 0; innerLoop < len; innerLoop++)
                {
                    if (theStringBuilder[loop + innerLoop] != value[innerLoop])
                    {
                        found = false;
                        break;
                    }
                }
                if (found)
                {
                    return loop;
                }
            }
            return NOT_FOUND;
        }
        public static string Substring(this StringBuilder theStringBuilder, int startIndex, int length)
        {
            return theStringBuilder == null ? null : theStringBuilder.ToString(startIndex, length);
        }
        public static bool AreEqual(this StringBuilder theStringBuilder, string compareString)
        {
            if (theStringBuilder == null)
            {
                return compareString == null;
            }
            if (compareString == null)
            {
                return false;
            }
            int len = theStringBuilder.Length;
            if (len != compareString.Length)
            {
                return false;
            }
            for (int loop = 0; loop < len; loop++)
            {
                if (theStringBuilder[loop] != compareString[loop])
                {
                    return false;
                }
            }
            return true;            
        }
        /// <summary>
        /// Compares one string to part of another string.
        /// </summary>
        /// <param name="haystack"></param>
        /// <param name="needle">Needle to look for</param>
        /// <param name="position">Looks to see if the needle is at position in haystack</param>
        /// <returns>Substring(theStringBuilder,offset,compareString.Length) == compareString</returns>
        public static bool IsStringAt(this StringBuilder haystack, string needle,int position)
        {
            if (haystack == null)
            {
                return needle == null;
            }
            if (needle == null)
            {
                return false;
            }
            int len = haystack.Length;
            int compareLen = needle.Length;
            if (len < compareLen + position)
            {
                return false;
            }
            for (int loop = 0; loop < compareLen; loop++)
            {
                if (haystack[loop+position] != needle[loop])
                {
                    return false;
                }
            }
            return true;
        }

    }
}
2 голосов
/ 21 июня 2011

ИМХО, вам не нужно использовать StringBuilder в этом случае ... StringBuilder более полезен при использовании в цикле.Как Microsoft говорит в В этой статье

Объект String является неизменным.Каждый раз, когда вы используете один из методов в классе System.String, вы создаете новый строковый объект в памяти, который требует нового выделения пространства для этого нового объекта.В ситуациях, когда необходимо выполнить повторные изменения строки, накладные расходы, связанные с созданием нового объекта String, могут быть дорогостоящими.Класс System.Text.StringBuilder можно использовать, когда вы хотите изменить строку без создания нового объекта.Например, использование класса StringBuilder может повысить производительность при объединении множества строк в цикле

Так что просто вы можете использовать String и избегать использования ToString () ...

...