在StringBuilder没有调用ToString()的情况下从空尾修剪空白的有效方法是什么.修剪()并返回到新的SB new StringBuilder(sb.ToString().Trim()).
Nic*_*sen 40
以下是扩展方法,因此您可以这样调用它:
sb.TrimEnd();
Run Code Online (Sandbox Code Playgroud)
此外,它返回SB实例,允许您链接其他调用(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;
}
Run Code Online (Sandbox Code Playgroud)
笔记:
1)如果为Null或Empty,则返回.
2)如果实际上不需要Trim,我们正在谈论一个非常快速的返回时间,可能最昂贵的调用是对char.IsWhiteSpace的单次调用.所以在不需要时调用TrimEnd实际上是零费用,而不是这些ToString().Trim()返回SB路由.
3)否则,如果需要修剪,最昂贵的是对char.IsWhiteSpace的多次调用(在第一个非空白字符处中断).当然,循环向后迭代; 如果所有都是空白,你最终会得到一个SB.Length为0.
4)如果遇到空格,则i索引保持在循环之外,这允许我们适当地剪切长度.在StringBuilder中,这是非常高效的,它只是设置一个内部长度整数(内部char []保持相同的内部长度).
UPDATE2:看看Ryan Emerle的优秀笔记如下,这些笔记纠正了我的一些误解(SB的内部工作比我做的要复杂得多):
StringBuilder在技术上是char []块的链接列表,所以我们不会在LOH中结束.调整长度在技术上并不像更改结束索引那么简单,因为如果移动到不同的块中,则必须维护容量,因此可能需要分配新的块.不过,你只在最后设置了Length属性,所以这似乎是一个很好的解决方案.Eric Lippert的相关详细信息:https://stackoverflow.com/a/6524401/62195
另外,请参阅这篇讨论.NET 4.0新StringBuilder实现的好文章: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
Run Code Online (Sandbox Code Playgroud)
在更改Length之后,您可以看到内部数组(m_ChunkChars)保持相同的大小,事实上,您可以在调试器中看到它甚至不会覆盖(在这种情况下为空白)字符.他们是孤儿.