Ответ 1
Ниже приведен метод расширения, поэтому его можно вызвать так:
sb.TrimEnd();
Кроме того, он возвращает экземпляр SB, позволяя вам sb.TrimEnd().AppendLine()
другие вызовы (sb.TrimEnd().AppendLine()
).
public static StringBuilder TrimEnd(this StringBuilder sb)
{
if (sb == null || sb.Length == 0) return sb;
int i = sb.Length - 1;
for (; i >= 0; i--)
if (!char.IsWhiteSpace(sb[i]))
break;
if (i < sb.Length - 1)
sb.Length = i + 1;
return sb;
}
Заметки:
1) Если ноль или пусто, возвращает.
2) Если на самом деле нет необходимости в Trim, мы говорим об очень быстром времени возврата, при этом, вероятно, самым дорогим вызовом является одиночный вызов char.IsWhiteSpace. Таким образом, практически нет затрат на вызов TrimEnd, когда он не нужен, в отличие от этих ToString(). Trim() обратно на маршруты SB.
3) Иначе, самой дорогой вещью, если необходима подстройка, являются множественные вызовы char.IsWhiteSpace (разрывы на первом непробельном символе). Конечно, цикл повторяется в обратном направлении; если все пробелы, вы получите SB.Length 0.
4) Если были обнаружены пробелы, индекс я сохраняется вне цикла, что позволяет нам соответствующим образом сократить длину. В StringBuilder это невероятно эффективно, оно просто устанавливает целое число внутренней длины (внутренний символ [] остается той же внутренней длины).
ОБНОВЛЕНИЕ 2: посмотрите отличные заметки Райана Эмерла следующим образом, которые исправляют некоторые из моих недоразумений (внутренняя работа SB немного сложнее, чем я предполагал):
StringBuilder - это технически связанный список блоков char [], поэтому мы не попадаем в LOH. Регулировка длины технически не так проста, как изменение конечного индекса, потому что если вы переходите в другой блок, необходимо сохранить Capacity, поэтому может потребоваться выделить новый блок. Тем не менее, вы устанавливаете только свойство Length в конце, так что это кажется отличным решением. Соответствующие подробности от Эрика Липперта: fooobar.com/questions/163664/...
Также см. Эту хорошую статью, в которой обсуждается новая реализация StringBuilder.NET 4.0: http://1024strongoxen.blogspot.com/2010/02/net-40-stringbuilder-implementation.html
------- ОБНОВИТЬ --------
Ниже показано, что происходит, когда длина StringBuilder изменяется (единственная реальная операция, выполняемая здесь для SB, и это только при необходимости):
StringBuilder sb = new StringBuilder("cool \t \r\n ");
sb.Capacity.Print(); // 16
sb.Length.Print(); // 11
sb.TrimEnd();
sb.Capacity.Print(); // 16
sb.Length.Print(); // 4
Вы можете видеть, что внутренний массив (m_ChunkChars) остается неизменным по размеру после изменения длины, и фактически вы можете видеть в отладчике, что он даже не перезаписывает (в данном случае пробельные символы). Они осиротели, это все.