在我的代码中的某些时候,我使用这种方法:
IndexOf(string str, int startIndex)
我之前也在进行一些计算,并且我使用第二个参数(startIndex)调用此方法,该参数等于作为第一个参数传递的字符串的长度。 当然,字符串中不存在这样的索引,如果我们做了类似的事情:
string[string.Length]
我们会得到IndexOutOfRangeException
该方法如何正常工作?在MSDN文档中明确指出,startIndex是字符串从零开始的索引。它是否有效并且不会抛出,因为String
类操作的char数组是以null结尾的?
我想确保我的程序不会在任何时候抛出。
答案 0 :(得分:5)
在documentation中明确提到:
索引编号从0开始.startIndex参数的范围是 0到字符串实例的长度。 如果startIndex等于 字符串实例的长度,方法返回-1 。
答案 1 :(得分:3)
public unsafe int IndexOf(char value, int startIndex, int count) {
if (startIndex < 0 || startIndex > Length)
throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
if (count < 0 || count > Length - startIndex)
throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_Count"));
fixed (char* pChars = &m_firstChar)
{
char* pCh = pChars + startIndex;
while (count >= 4)
{
// .. some search
}
while (count > 0)
{
// .. some search
}
}
return -1;
}
如您所见,ArgumentOutOfRangeException
仅在使用比字符串长度更大的startIndex
时才会被抛出。由于你自己传递长度,这不是问题。如果你要传递一个大于它的数字,你会看到例外:
Console.WriteLine("foo".IndexOf('a', 3)); // -1
Console.WriteLine("foo".IndexOf('a', 4)); // throws ArgumentOutOfRangeException
现在,我们实际上并未调用上面显示的IndexOf
。相反,我们称之为以下签名:
public int IndexOf(char value, int startIndex) {
return IndexOf(value, startIndex, this.Length - startIndex);
}
因此,对于上面的count
参数,传递值this.Length - startIndex
。由于startIndex
等于长度,count
将为零。
因此,我们在上面的实现中看到的两个while循环根本不会执行。因此,返回默认结果-1
。
(小注意:我使用的是.NET Core源代码,因为.NET Framework reference source不包含此方法的来源。虽然实现应该大致相同。)
至于为什么你可以在字符串结束后开始搜索,我有一个简单的解释可能是原因。如果你看一个字符串,你可以开始在多个点搜索。我们使用"foo bar"
作为字符串:
Index: 0 1 2 3 4 5 6
Character: f o o b a r
Points: ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑
0 1 2 3 4 5 6 7
正如您所看到的,对于长度为7的字符串,在字符之前或之后有8个点。当您指定诸如起始索引之类的内容时,您实际上并不是在谈论字符索引,而是指向字符索引。角色之间的空间。通过使用"foo bar".Substring(5, 1)
可以明显看出第5点和第6点(5 + 1)之间的字符。这也是str.Substring(str.Length)
实际上用于获取字符串末尾的空字符串的原因。
答案 2 :(得分:2)
如果startIndex等于字符串实例的长度,则该方法返回-1。
至于为什么如果index==length
像数组访问器一样,它不会抛出异常,框架设计者必须回答这个问题,因为文档没有说明,而且C#源代码最终调用内部C函数..一些未经过教育的猜测:
答案 3 :(得分:2)
MSDN清楚地说明了它可以抛出的异常。例如:
ArgumentOutOfRangeException
startIndex小于0(零)或大于此长度 字符串。
接着说:
索引编号从0开始.startIndex参数的范围是 0到字符串实例的长度。如果startIndex等于 字符串实例的长度,方法返回-1。
因此,关于例外情况确实没有猜测。