繁体   English   中英

如何更好地处理索引超出范围

[英]How to handle Index out of range in a better way

我的代码给了我某个输入的索引超出范围异常。 下面是有问题的代码:

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 看起来不太好。

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

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

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

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

就像是:

int index = 11;

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

snippetElements[11]是第 12 个元素。

if (snippetElements.Length >= 12)

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

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

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...)还是引用类型(字符串、您自己的类...)。

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

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

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM