我明白我可以调用ToString()。IndexOf(...),但我不想创建额外的字符串。我明白我可以手动编写搜索例程。我只是想知道为什么这样的例程在框架中不存在。为什么StringBuilder没有IndexOf方法?
回答
不幸的是,为String实现的许多方法可能已经为StringBuilder实现,但还没有完成。考虑使用扩展方法来添加你关心的内容。
在StringBuilder
上调用ToString()
不会创建额外的对象,令人困惑。在内部,StringBuilder
存储一个String对象,用于执行;调用ToString()
只是返回该对象。
我知道这是一个老问题,但是我写了一个扩展方法,在StringBuilder
上执行IndexOf
。在下面。我希望它可以帮助任何人发现这个问题,无论是从谷歌搜索或搜索StackOverflow。
/// <summary>
/// Returns the index of the start of the contents in a StringBuilder
/// </summary>
/// <param name="value">The string to find</param>
/// <param name="startIndex">The starting index.</param>
/// <param name="ignoreCase">if set to <c>true</c> it will ignore case</param>
/// <returns></returns>
public static int IndexOf(this StringBuilder sb, string value, int startIndex, bool ignoreCase)
{
int index;
int length = value.Length;
int maxSearchLength = (sb.Length - length) + 1;
if (ignoreCase)
{
for (int i = startIndex; i < maxSearchLength; ++i)
{
if (Char.ToLower(sb[i]) == Char.ToLower(value[0]))
{
index = 1;
while ((index < length) && (Char.ToLower(sb[i + index]) == Char.ToLower(value[index])))
++index;
if (index == length)
return i;
}
}
return -1;
}
for (int i = startIndex; i < maxSearchLength; ++i)
{
if (sb[i] == value[0])
{
index = 1;
while ((index < length) && (sb[i + index] == value[index]))
++index;
if (index == length)
return i;
}
}
return -1;
}
据说[使用String.ToUpperInvariant方法而不是String.ToLowerInvariant方法,当您规范化字符串进行比较](https://docs.microsoft.com/en-us/dotnet/standard/base-types/best-practices -strings#建议换字符串使用)。我想这对于字符比较也是正确的:[Char.ToUpper和Char.ToLower的工作方式与上一节中介绍的String.ToUpper和String.ToLower方法类似](https://docs.microsoft.com/en-us/dotnet/standard/base-types/best-practices-strings#chartoupper-and-chartolower) – Sergey 2018-02-24 14:28:08
Fair call;随时对上述帖子进行编辑。 – Dennis 2018-02-26 02:11:20
对不起,我错了。实际上微软已经优化了* ToUpperInvariant()*,而不是* ToUpper()*。在这种情况下,默认情况下,我们不能提供* ToUpperInvariant()*,只要它可能导致某些语言(如土耳其语)的错误比较。所以,在这方面,你的代码是绝对正确的。 – Sergey 2018-02-26 10:55:04
- 1. 为什么Linq中没有IndexOf(字符串值)方法?
- 2. 为什么indexOf无法找到对象?
- 3. QGraphicsItem:为什么没有`stackAfter`方法?
- 4. 为什么XElement没有GetAttributeValue方法?
- 5. 为什么Object [ID]没有方法'Animate'?
- 6. 为什么Ruby没有is_an?方法?
- 7. 为什么NStepLSTM没有reset_state方法?
- 8. 为什么org.lwjgl.opengl.GL43类没有glDrawElements方法?
- 9. 为什么GLAutoDrawable没有方法addMouseListener将
- 10. 为什么ObservableCollection没有RemoveAll方法?
- 11. 为什么SerializationInfo没有TryGetValue方法?
- 12. Mongoid为什么没有“事务”方法?
- 13. 为什么DataTable.Rows没有.Where()方法?
- 14. 为什么没有Array.IsNullOrEmpty()方法?
- 15. 为什么GLSurfaceView.Renderer中没有onSurfaceDestroyed方法?
- 16. 为什么Node.js Assert没有notOk()方法?
- 17. 为什么Object类没有Thread方法
- 18. 为什么没有Stream.flatMap(Collection)方法?
- 19. 为什么没有Convert.toFloat()方法?
- 20. 为什么StringBuilder无法添加AppendLine?
- 21. HtmlDivElement没有法 '的indexOf'
- 22. 有没有什么方法可以使用'unset'作为方法?
- 23. 为什么IndexOf返回-1?
- 24. 为什么'abc'.indexOf([])=== 0?
- 25. 为什么我们需要在stringbuilder中使用toString方法
- 26. 为什么没有没有参数的IsNullOrEmpty重载方法?
- 27. 为什么Enumerable中的方法可能没有方法体?
- 28. 为什么indexOf(char)值为0?
- 29. 有没有简短的方法来写indexOf在100以上?
- 30. 无法在JSON字符串上使用.indexof,因为它没有方法'indexof'javascript
如果StringBuilder的被要求修改本身Tthen创建一个新的* *字符串这不是问题的情况下是正确的,内部缓冲器的可变性不暴露于托管代码。 – ShuggyCoUk 2009-09-01 00:04:06
@ ShuggyCoUk:我的评论有点过分。我已将其删除。 – 2009-09-01 00:11:15
为了澄清以前的评论,调用ToString没有太多的开销。但是在你调用它之后,StringBuilder的下一个修改将会导致拷贝开销。 (这是一个有效的优化,因为ToString通常是对StringBuilder完成的最后一件事情。)因此,类似String的方法的高效实现不能使用ToString,这样就排除了原始海报问题的简单解决方案。 – 2009-09-01 02:10:23