如何以更好的方式处理索引超出范围

时间:2013-02-08 11:04:47

标签: c#

我的代码为某个输入提供了Index of Range 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在代码中表现不佳。

6 个答案:

答案 0 :(得分:5)

是的,这是一篇旧帖子,但仍然有帮助。你可以使用我觉得更清洁的东西:

string a = snippetElements.ElementAtOrDefault(10) ?? "hello"; 
string b = snippetElements.ElementAtOrDefault(11) ?? "world";

答案 1 :(得分:1)

  

有人可以建议更好的方法来编写此支票。不知何故   第11号在代码中表现不佳。

您正在使用11索引访问该元素,如果您的变量中包含该索引,那么您可以在支票中使用该索引,否则11在您的支票中就可以了。您的支票应为if(index < snippetElements.Length)

类似的东西:

int index = 11;

if(index < snippetElements.Length)
{
   string b = snippetElements[index] == null ? "" : "world";
}

答案 2 :(得分:1)

snippetElements[11]是第12个元素。

if (snippetElements.Length >= 12)

只要您实际使用[10]和[11]索引,在if语句中使用12就不会出错。

答案 3 :(得分: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";

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

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

答案 4 :(得分:0)

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

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

string a = snippetElements.Length >= 12 ? "hello" : string.Empty; 
string b = snippetElements.Length >= 12 ? "world" : string.Empty;

答案 5 :(得分: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。