开发者

Is it required to check before replacing a string in StringBuilder (using functions like "Contains" or "IndexOf")?

Is there any method IndexOf or Contains in C#. Below is the code:

var sb = new StringBuilder(mystring);
sb.Replace(开发者_JAVA百科"abc", "a");
string dateFormatString = sb.ToString();

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


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

As you might have noticed I am using ToString() above again and again which I want to avoid as it is creating new string everytime. Can you help me how can I avoid it?


If the StringBuilder doesn't contain "def" then performing the replacement won't cause any problems, so just use:

var sb = new StringBuilder(mystring);
sb.Replace("abc", "a");
sb.Replace("def", "aa");
sb.Replace("ghi", "assd");


There's no such method in StringBuilder but you don't need the Contains tests. You can simply write it like this:

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

If the string in the first parameter to Replace is not found then the call to Replace is a null operation—exactly what you want.

The documentation states:

Replaces all occurrences of a specified string in this instance with another specified string.

The way you read this is that when there are no occurrences, nothing is done.


You can write a class that extends methods to the StringBuilder object. Here, I have added IndexOf, Substring, and other methods to the StringBuilder class. Just put this class in your project.

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;
        }

    }
}


IMHO you don't have to use StringBuilder in this case... StringBuilder is more useful when used in a loop. Like Microsoft say in In this article

The String object is immutable. Every time you use one of the methods in the System.String class, you create a new string object in memory, which requires a new allocation of space for that new object. In situations where you need to perform repeated modifications to a string, the overhead associated with creating a new String object can be costly. The System.Text.StringBuilder class can be used when you want to modify a string without creating a new object. For example, using the StringBuilder class can boost performance when concatenating many strings together in a loop

So simply you can use String and avoid use ToString()...

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜