我知道我可以调用ToString()。IndexOf(...),但我不想创建额外的字符串。我知道我可以手动编写搜索例程。我只是想知道为什么框架中不存在这样的例程。
答案 0 :(得分:43)
我知道这是一个老问题,但是我编写了一个在IndexOf
上执行StringBuilder
的扩展方法。它在下面。我希望通过 Google 搜索或搜索 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;
}
答案 1 :(得分:6)
不幸的是,为String实现的许多方法都可以为StringBuilder实现,但是没有完成。考虑使用扩展方法添加您关心的内容。
答案 2 :(得分:0)
在ToString()
上调用StringBuilder
不会造成额外的对象,令人困惑。在内部,StringBuilder
存储一个String对象,以提高性能;调用ToString()
只会返回该对象。
答案 3 :(得分:-1)
丹尼斯,很好的解决方案。谢谢。 我建议对其进行一些优化:
public static int IndexOf(
this StringBuilder sb,
string value,
int startIndex,
bool ignoreCase)
{
int len = value.Length;
int max = (sb.Length - len) + 1;
var v1 = (ignoreCase)
? value.ToLower() : value;
var func1 = (ignoreCase)
? new Func<char, char, bool>((x, y) => char.ToLower(x) == y)
: new Func<char, char, bool>((x, y) => x == y);
for (int i1 = startIndex; i1 < max; ++i1)
if (func1(sb[i1], v1[0]))
{
int i2 = 1;
while ((i2 < len) && func1(sb[i1 + i2], v1[i2]))
++i2;
if (i2 == len)
return i1;
}
return -1;
}