字符串的Split方法是否保证结果数组中的顺序?

9

在进行流畅的谷歌搜索后,我们没有得到答案,所以问题是:

String.Split方法是否确保返回的子字符串与它们在初始字符串中的位置相对应?


2
你得到了一个好答案,也许是我们能期望的最好的答案。不过我必须指出,仅仅因为当前的实现将事物放在预期的顺序中,并不意味着这是真正的保证。话虽如此,BCL团队改变顺序是愚蠢的。这根本没有任何意义。 - Jim Mischel
感谢您有用的评论,Jim。虽然更改String.Split中的顺序不太可能,但最好避免期望从拆分方法中获得一致的顺序。 - iburlakov
2
相反,我期望split方法的结果是一致有序的。如果我不能依赖顺序,那么String.Split几乎就没有用处了。我认为这个行为没有被明确说明,是因为没有人想到要指出这么“显而易见”的事情。我认为他们应该记录这种行为。 - Jim Mischel
@JimMischel:鉴于一些程序员随意通过更改未记录的任何行为来进行“性能优化”,而不考虑任何代码是否依赖这些行为,我同意记录甚至是程序员有权利利用的“显而易见”的行为可能是一个好主意。如果框架有一个“substring”对象类型,它的行为类似于String但保存了对另一个String的引用以及起始偏移量和长度(如果GC特殊处理,则可以提高性能),那么这可能是有意义的... - supercat
为了使具有多个分隔符类型的拆分工作,可以通过在一个分隔符类型上拆分主字符串,然后使用其他分隔符将结果字符串细分。实现可以自由返回任意顺序的字符串,可能比必须按源字符串顺序返回字符串的实现略快一点,因此理论上,在没有相反说明的情况下,疯狂的程序员实现拆分可能会使用这样的实现。 - supercat
2个回答

11
根据ILSpy显示string.Split的内部情况,答案是
private string[] InternalSplitKeepEmptyEntries(
    int[] sepList, int[] lengthList, int numReplaces, int count)
{
    int num = 0;
    int num2 = 0;
    count--;
    int num3 = (numReplaces < count) ? numReplaces : count;
    string[] array = new string[num3 + 1];
    int num4 = 0;
    while (num4 < num3 && num < this.Length)
    {
        array[num2++] = this.Substring(num, sepList[num4] - num);
        num = sepList[num4] + ((lengthList == null) ? 1 : lengthList[num4]);
        num4++;
    }
    if (num < this.Length && num3 >= 0)
    {
        array[num2] = this.Substring(num);
    }
    else
    {
        if (num2 == num3)
        {
            array[num2] = string.Empty;
        }
    }
    return array;
}

所有元素(例如变量array)始终按升序处理,不会进行排序。

MSDN对于string.Split的文档也列出了结果与原始字符串中顺序相同的示例。

正如Jim Mischel上面指出的那样,这只是当前的实现,可能会改变。


4
确凿的证据。速度也很快。 - captncraig

2
是的,它确实可以。否则它将毫无用处。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接