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

13

ли какой-либо метод 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 (), чего я хочу избежать, поскольку он создает новую строку каждый раз. Можете ли вы помочь мне, как я могу избежать этого?

RE: "Есть ли метод IndexOf или содержится в C #". C # это язык программирования. Сам язык не определяет какие-либо конкретные методы, будь то IndexOf, Contains или любые другие. Вместо этого C # дает вам возможность определять ваши методы так, как вы считаете нужным. Вы можете прочитать больше об этом наmsdn.microsoft.com/en-us/library/ms173114.aspx Методы в .NET относятся к типам, а типы, как правило, не зависят от языка - вы можете создавать их на любом языке, который поддерживает типы. Andrew Savinykh
Почему бы вам просто не заменить без проверки содержимого, так как он должен игнорировать текст в любом случае, если он не содержит искомую строку Yet Another Geek
Достаточно легко определить, имеет ли конкретный тип метод с указанным именем или нет, посмотрев на MSDN. В случае класса StringBuilder статья здесь:msdn.microsoft.com/en-us/library/system.text.stringbuilder.aspxКак легко увидеть из этой статьи, этот класс не содержит ни методов IndexOf, ни Contains. В более неясных случаях вы можете захотеть использовать .NET Reflector, чтобы выбрать изнутри и посмотреть, какие методы может иметь класс. Andrew Savinykh

Ваш Ответ

4   ответа
2

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

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

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

19

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

var sb = new StringBuilder(mystring);
sb.Replace("abc", "a");
sb.Replace("def", "aa");
sb.Replace("ghi", "assd");
Это также хорошая идея с точки зрения эффективности. ДелатьContains а затемReplace означает, что вы ищете строку дважды. С точки зрения высокого уровня, «Заменить все экземпляры"def" с участием"aa" «по-прежнему имеет смысл, если нет случаев"def". Brian
@Ricketts: Нет - подумайте, во что превращается этот код:GenerateReplacement() метод вызывается, а затем результат передается вReplace в качестве аргумента. Jon Skeet
@Matt: Это отвечает цели, стоящей за вопросом верхнего уровня, к удовлетворению ОП. Это не тот ответ, который я бы дал в эти дни, но он касается того, что пытался сделать ОП. Jon Skeet
Что если новая строка является методом, который генерирует строку? Такsb.Replace("abc", GenerateReplacement()) будет методGenerateReplacement() исполняться только в том случае, если"abc" существует? Ricketts
Это не отвечает на вопрос - вопрос был о.IndexOf для StringBuilder ... Matt
3

который расширяет методы для объекта 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;
        }

    }
}
Это не то, как работает Contains - он использует локаль и следует правилам сравнения строк в Юникоде, которые намного сложнее, чем простое посимвольное сравнение, реализованное здесь. bright
5

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

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

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

В документации говорится:

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

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

Похожие вопросы