Строка или возвращаемые значения StringBuilder?

for line in lines:
    if '=' not in line:
        time_data = line.split('\n')
        for time in time_data:
            data_lines.append(time+'\n')
        data_lines = [data.replace(';', ',') for data in data_lines]

Попробуйте и дайте мне знать

18
задан John Bubriski 7 May 2009 в 12:52
поделиться

11 ответов

Возвращать StringBuilder, если вы собираетесь дополнительно изменить строку, в противном случае вернуть строку. Это вопрос API.

Относительно эффективности. Поскольку это неопределенный / общий вопрос без каких-либо подробностей, я думаю, что изменчивость против неизменности важнее производительности. Изменчивость - это проблема API, позволяющая вашему API возвращать изменяемые объекты. Длина строки не имеет к этому отношения.

Тем не менее. Если вы посмотрите на StringBuilder.ToString с Reflector:

public override string ToString()
{
    string stringValue = this.m_StringValue;
    if (this.m_currentThread != Thread.InternalGetCurrentThread())
    {
        return string.InternalCopy(stringValue);
    }
    if ((2 * stringValue.Length) < stringValue.ArrayLength)
    {
        return string.InternalCopy(stringValue);
    }
    stringValue.ClearPostNullChar();
    this.m_currentThread = IntPtr.Zero;
    return stringValue;
}

Вы можете увидеть, что он может сделать копию, но если вы измените его с помощью StringBuilder, тогда он сделает копию (это то, что я могу сказать, смысл m_currentThread потому что проверяет это и копирует, если он не соответствует текущему потоку.)

Я предполагаю, что конец этого заключается в том, что если вы не измените StringBuilder, то вы не скопируете строку, а длина не имеет отношения к эффективности (если вы не нажмете это 2-й, если).

ОБНОВЛЕНИЕ

Система. String - это класс, который означает, что это ссылочный тип (в отличие от типа значения), поэтому "string foo;" это по сути указатель. (Когда вы передаете строку в метод, она передает указатель, а не копию.) System.String является изменяемой внутри mscorlib, но неизменной за ее пределами, как StringBuilder может манипулировать строкой.

Поэтому, когда вызывается ToString () он возвращает свой внутренний строковый объект по ссылке. На данный момент вы не можете изменить его, потому что ваш код не находится в mscorlib. Если установить для поля m_currentThread значение ноль, то любые дальнейшие операции с StringBuilder приведут к тому, что он скопирует строковый объект, чтобы его можно было изменить и не изменять строковый объект, возвращенный в ToString (). Учтите это:

StringBuilder sb = new StringBuilder();
sb.Append("Hello ");

string foo = sb.ToString();

sb.Append("World");

string bar = sb.ToString();

Если StringBuilder не сделал копию, то в конце foo будет «Hello World» потому что StringBuilder изменил его. Но поскольку он сделал копию, foo по-прежнему просто «Hello», а bar - «Hello World».

Это проясняет весь вопрос возврата / ссылки?

23
ответ дан 30 November 2019 в 07:13
поделиться

Я бы сказал, что метод должен возвращать sb.ToString (). Если логика, связанная с созданием объекта StringBuilder (), должна измениться в будущем, для меня имеет смысл, чтобы она изменялась в методе, а не в каждом сценарии, который вызывает метод и затем выполняет что-то еще

3
ответ дан 30 November 2019 в 07:13
поделиться

Я не думаю, что производительность должна быть фактором в этом вопросе. В любом случае кто-то будет вызывать sb.ToString (), чтобы вы куда-нибудь взяли удар.

Более важный вопрос - каково намерение метода и цели. Если этот метод является частью компоновщика, вы можете вернуть компоновщик строк. В противном случае я бы возвратил строку.

Если бы это было частью общедоступного API, я бы склонялся к возврату строки вместо компоновщика.

5
ответ дан 30 November 2019 в 07:13
поделиться

StringBuilder - это деталь реализации вашего метода. Вы должны возвращать строку, пока она не станет проблемой производительности, после чего вам следует изучить другой шаблон (например, шаблон посетителей ), который может помочь вам ввести косвенное обращение и защитить вас от внутренних решений реализации.

Строки являются всегда хранится в куче, поэтому вам будет возвращена ссылка, если возвращаемый тип - строка. Однако нельзя рассчитывать, что две одинаковые строки имеют одинаковые ссылки. В общем, безопасно думать о строке как о типе значения, даже если это на самом деле ссылочный тип.

3
ответ дан 30 November 2019 в 07:13
поделиться

Я думаю, это зависит от того, что вы делаете со строкой, когда она покидает метод. Если вы собираетесь продолжить добавление к нему, вы можете рассмотреть возможность возврата stringbuilder для большей эффективности. Если вы всегда собираетесь вызывать .ToString () для него, вы должны сделать это внутри метода для лучшей инкапсуляции.

1
ответ дан 30 November 2019 в 07:13
поделиться

Я бы вернул строку почти во всех ситуациях, особенно если метод является частью общедоступного API.

Исключением будет, если ваш метод всего один часть более крупного частного процесса «сборки» и вызывающий код будут выполнять дальнейшие манипуляции. В таком случае я мог бы рассмотреть вопрос о возвращении StringBuilder .

1
ответ дан 30 November 2019 в 07:13
поделиться

Поскольку вы больше не собираетесь его изменять,

return sb.ToString();

должно быть наиболее эффективным

1
ответ дан 30 November 2019 в 07:13
поделиться

Вернуть sb.ToString (). Ваш метод должен быть сосредоточен только на предмете (в этом случае создайте мне строку), а не возвращаться для дальнейшей манипуляции с IMO, вы можете столкнуться со всевозможными проблемами, если его не утилизировать.

1
ответ дан 30 November 2019 в 07:13
поделиться

Это зависит от того, что вы планируете делать с выходными данными. Я бы вернул строку лично. Таким образом, если вам нужно изменить метод в будущем, чтобы не использовать строитель строк, вы можете сделать это, так как вы не будете привязаны к этому как к возвращаемому значению. 12100 Подумав об этом, ответ гораздо яснее. Вопрос о том, что следует вернуть, действительно отвечает на этот вопрос. Возвращаемый объект должен быть строкой. Причина в том, что если вы задаете вопрос: «Есть ли причина возвращать объект StringBuilder, когда будет работать строка?» тогда ответ - нет. Если бы была причина, то о возвращении строки не могло быть и речи, поскольку необходимы методы и свойства строителя строк.

1
ответ дан 30 November 2019 в 07:13
поделиться

Если вам нужно добавить в строку больше материала и использовать другие функции, связанные с построителем строк, верните построитель строк. В противном случае, если вы просто используете саму строку, верните ее.

Есть и другие технические соображения, но это касается самого высокого уровня.

0
ответ дан 30 November 2019 в 07:13
поделиться

Методу было дано конкретное задание, и следует ожидать его завершения и возврата готового результата, который не требует дальнейшей обработки. Возвращайте StringBuilder только тогда, когда он вам действительно нужен. В этом случае также добавьте что-то в имя метода, чтобы указать, что вы возвращаете что-то особенное.

0
ответ дан 30 November 2019 в 07:13
поделиться
Другие вопросы по тегам:

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