C# 防止索引超出范围错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10113680/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 12:29:22  来源:igfitidea点击:

Preventing Index Out of Range Error

c#

提问by Victor

I want to write a check for some conditions without having to use try/catch and I want to avoid the possibilities of getting Index Out of Range errors

我想对某些条件进行检查而不必使用 try/catch 并且我想避免出现索引超出范围错误的可能性

if (array.Element[0].Object.Length > 0 || array.Element[1].Object.Length > 0) //making sure there's at least one Object array that has values
 {                
    if (array.Element[0].Object[0].Item.Length != 0 || array.Element[1].Object[0].Item.Length != 0) //this is where I check that at least one of the Items (strings) is not empty
       {
           // execute code here
       }
 }

So the problem I am facing is that in the second check I need to see whether I have one Item that is not empty. However, If I don't have Element[1], I get the Index Out of Range exception. The problem is that there could be 2 Elements and one(or both) of them may have empty Object arrays. The code will have to be executed only if one of thos Item strings is not empty.

所以我面临的问题是,在第二次检查中,我需要查看是否有一个非空的 Item。但是,如果我没有Element[1],我会得到索引超出范围异常。问题是可能有 2 个元素,其中一个(或两个)可能有空的 Object 数组。仅当 Item 字符串之一不为空时,才必须执行代码。

Hopefully, I explained it well. How do I go about avoiding getting that exception under any condition?

希望我解释得很好。在任何情况下,我如何避免获得该异常?

采纳答案by deltree

Alright, you need some better null checkingand some more cautious code here.

好的,您需要一些更好的空检查和一些更谨慎的代码。

if (array.Element[0].Object.Length > 0 || array.Element[1].Object.Length > 0) //making sure there's at least one Object array that has values
{                
   if (array.Element[0].Object[0].Item.Length != 0 || array.Element[1].Object[0].Item.Length != 0) //this is where I check that at least one of the Items (strings) is not empty
   {
       // execute code here
   }
}

is just unacceptable.

是不可接受的。

First, let's null check

首先,让我们做空检查

if (array != null)
{
    if (array.Element != null)

for simplicity, you could use &&

为简单起见,您可以使用 &&

if (array != null && array.Element != null)

then, inside that if, we use a for loop (since you're stuck on arrays) and null check it

然后,在那个 if 里面,我们使用 for 循环(因为你被困在数组上)并空检查它

for (int i = 0; i < array.Element; ++i)
{
    if (array.Element[i] != null && array.Element[i].Object != null)
    {

then, since you have nested arrays, we loop again. This is called a nested loop, and it's generally bad practice, I'll show you why it works in a second.

然后,由于您有嵌套数组,我们再次循环。这称为嵌套循环,这通常是不好的做法,我将向您展示为什么它会起作用。

for (int o = 0; o < array.Element[i].Object.length; ++o)
{
    if (array.Element[i].Object[o] != null && !string.IsNullOrEmpty(array.Element[i].Object[o].Item))
    {

Now, with all of that ugly nested loopyness, we've found out that your Item is not null. On top of that, you have access to ALL of the potential values here, and can group them as you like. Here's how I would put the whole thing together for simplification.

现在,由于所有这些丑陋的嵌套循环,我们发现您的 Item 不为空。最重要的是,您可以访问此处的所有潜在值,并可以根据需要对它们进行分组。这是我将整个事情放在一起以进行简化的方式。

List<string> arrayValues = new List<string>();
if (array != null && array.Element != null)
{
    for (int i = 0; i < array.Element.length; ++i)
    {
        //bool found = false;
        if (array.Element[i] != null && array.Element[i].Object != null)
        {
            for (int o = 0; o < array.Element[i].Object.length; ++o)
            {
                if (array.Element[i].Object[o] != null && !string.IsNullOrEmpty(array.Element[i].Object[o].Item))
                {
                    arrayValues.Add(array.Element[i].Object[o].Item);
                    //if you want to drop out here, you put a boolean in the bottom loop and break and then break out of the bottom loop if true
                    //found = true;
                     //break;
                }
            }
        }
        //if (found)
        //  break;
    }
}
if (arrayValues.Count > 0)
{
    //do stuff with arrayValues
}

回答by Ryan

Could you do something like:

你能不能做这样的事情:

if(array.Element[0] != null || array.Element[1] != null){
    //execute code
}

回答by nothrow

Your code is probably subject to refactor.

您的代码可能需要重构。

I assume it can work this way:

我认为它可以这样工作:

var obj = array.Element.FirstOrDefault(x => x.Object.Length > 0);
if (obj != null)
{
  if (obj.Object[0].Item.Length != 0) 
  {
    // do whatever is necessary
  }
}

回答by Kevin P. Rice

Place both tests together using the short-circuit &&so that the second test doesn't occur if the first fails:

使用短路将两个测试放在一起,&&以便在第一个测试失败时不会发生第二个测试:

object element0 = array.Element[0].Object;
object element1 = array.Element[1].Object;

// Ensure at least one Object array has a non-empty value.
if ((element0.Length > 0 && !string.IsNullOrEmpty((string)element0.Object[0].Item))
    || (element1.Length > 0 && !string.IsNullOrEmpty((string)element1.Object[1].Item)))
{
    // ...
}

I am presuming it is Object[1]causing the exception--you weren't clear on that. If it is Element[1]that causes the exception (or both), then you need to pre-test the length of the array:

我假设它Object[1]导致了异常——你不清楚。如果是Element[1]导致异常(或两者兼有),则需要预先测试数组的长度:

if ((array.Element[0].Length != 0 && HasValue(array.Element[0].Object))
    || (array.Element[1].Length > 1 && HasValue(array.Element[1].Object)))
{
    // ...
}

// <summary>
// Returns true if the specified string array contains a non-empty value at
// the specified index.
// </summary>
private bool HasValue(System.Array array, int index)
{
    return array.Length > index && 
        !string.IsNullOrEmpty((string)array.Object[index].Item);
}

回答by Patrick G

I think you can put your check in right before your first if Check.

我想你可以在你的第一个 if Check 之前把你的支票放进去。

if (array.Length > 1 && array.Element[0].Object.Length > 0 || array.Element[1].Object.Length > 0) //making sure there's at least one Object array that has values
 {                
    if (array.Element[0].Object[0].Item.Length != 0 || array.Element[1].Object[0].Item.Length != 0) //this is where I check that at least one of the Items (strings) is not empty
       {
           // execute code here
       }
 }

This should just short-circuit out if your array doesn't have both Elements.

如果您的阵列没有两个元素,这应该只是短路。

回答by Dawit Selesh

for (long i = 0; i <= (output3.Length); i++)
{
    output1.WriteByte(output3[i]); -----> index out of range exception correct it
    output1.WriteByte(output3rx[i]);
}