4

我的代码给了我某个输入的 Index out of Range 异常。下面是有问题的代码:

string[] snippetElements = magic_string.Split('^');

string a = snippetElements[10] == null ? "" : "hello";
string b = snippetElements[11] == null ? "" : "world";

对于那个特定的输入,数组 snippetElements 中只有一个元素,因此在尝试索引第 10 个和第 11 个元素时,我遇到了异常。

现在,我介绍了以下检查:

if (snippetElements.Length >= 11)
{
    string a = snippetElements[10] == null ? "" : "hello"; 
    string b = snippetElements[11] == null ? "" : "world";
}

有人可以建议一个更好的方法来写这张支票。不知何故,数字 11 在代码中看起来不太好。

4

6 回答 6

10

是的,这是一个旧帖子,但仍然很有帮助。你可以使用我认为更清洁的这个:

string a = snippetElements.ElementAtOrDefault(10) ?? "hello"; 
string b = snippetElements.ElementAtOrDefault(11) ?? "world";
于 2018-01-15T14:46:05.263 回答
1

您可以将问题概括为这样的扩展方法

public static class ArrayExtensions
{
    public static bool TryIndex<T>(this T[] array, int index, out T result)
    {
        index = Math.Abs(index);

        result = default(T);
        bool success = false;

        if (array != null && index < array.Length)
        {
            result = (T)array.GetValue(index);
            success = true;
        }

        return success;
    }
}

并将您的代码转换为:

string[] snippetElements = magic_string.Split('^');

string a = null;
string b = null;

if (snippetElements.TryIndex(10, out a) && snippetElements.TryIndex(11, out b))
{
}

或者,更像您的源代码并使用TryIndex(...)扩展方法:

string[] snippetElements = magic_string.Split('^');

string a = null;
string b = null;

snippetElements.TryIndex(10, out a);
snippetElements.TryIndex(11, out b);

a = a ?? "hello"; // Null coalesence ?? operator is great!
b = b ?? "world";

它使数组索引访问更安全,因为您的代码永远不会 throw ArgumentOutOfRangeException

请注意,此扩展方法适用于任何类型的数组,无论其类型如何!无论是值类型(int、byte...)还是引用类型(string、您自己的类...)。

于 2013-02-08T11:31:47.883 回答
1

有人可以建议一个更好的方法来写这张支票。不知何故,数字 11 在代码中看起来不太好。

那么您正在使用11索引访问元素,如果您的变量中有该索引,那么您可以在您的检查中使用它,否则11在您的检查中很好。你的支票应该是if(index < snippetElements.Length)

就像是:

int index = 11;

if(index < snippetElements.Length)
{
   string b = snippetElements[index] == null ? "" : "world";
}
于 2013-02-08T11:06:51.287 回答
1

snippetElements[11]是第 12 个元素。

if (snippetElements.Length >= 12)

只要您实际使用 [10] 和 [11] 索引,在 if 语句中使用 12 看起来并没有错。

于 2013-02-08T11:07:01.050 回答
0

这里的逻辑是错误的。
如果您的Split方法生成的元素少于 12 个,则您对数组的索引snippetElements只能从数组的零到 (Length - 1)。

在这种情况下,索引 10 或 11 处没有元素。而且,在任何情况下,如果snippetElement.Lenght等于或大于 12,则数组中的元素不能为空。或者它们包含一个字符串,或者它们将是空字符串。
你可以写

string a = snippetElements.Length >= 12 ? "hello" : string.Empty; 
string b = snippetElements.Length >= 12 ? "world" : string.Empty;
于 2013-02-08T11:13:26.780 回答
0

现在可能为时已晚,但对于遇到同样问题的其他人来说,这就是我解决问题的方法。我通常在 for 循环中使用这个逻辑。

int index = 10;
string a = (index < snippetElements?.Length) ? snippetElements[index] : string.Empty; 

snippetElements?.Length检查 snippetElements 是否不为空,然后调用其 Length 属性。访问空数组的 Length 属性会导致异常。 snippetElements[index](您可以在示例中将其替换为“hello”)仅当索引位于数组的范围内时才能访问。否则,它将 String.Empty 分配给 a。

于 2021-01-07T08:22:42.137 回答