C#数组索引总是超出范围

3

我在C#中遇到了一个非常奇怪的问题,不确定是什么原因。请看下面的代码片段:

foreach(string bed in bayBeds)
{
    string[] bedProperties = bed.Split(new char[] { '^' });
    if (bedProperties.Length > 0)
    {
        string genderCode = bedProperties[1];
        if (genderCode == "M")
        {
            bedCount = bedCount + bayBeds.Count;
            break;
        }
    }
}

在这个例子中,字符串数组bedProperties被测试以查看其长度是否大于0,如果是,则检索元素1。问题在于,此代码始终会生成越界异常。我可以修改为返回bedProperties.Length,这将给我一个值(例如3,这实际上是此对象中的属性数量),但任何尝试通过索引获取数组元素(例如bedProperties[1]、bedProperties[0]等)都将始终给我一个越界异常。始终如此。我不明白为什么会这样。
请理解我对C#不太熟悉,所以如果我犯了一些非常愚蠢的错误,请不要过于苛刻。
谢谢 - 我非常感谢所有的帮助。
编辑:根据下面许多帮助,我找到了问题。
为了清楚起见,这是整个函数:
public int returnMaleBedTotal(string bedCollection) {
      // determine total number of male beds for a bay
      int bedCount = 0;
      if (bedCollection.Length > 0) {
        List<string> theBays = new List<string>(bedCollection.Split(new char[] { '@' }));

        // at this point we have the bays, so iterate them and extract the beds in the bays
        foreach (string bayBedCollection in theBays) {
          List<string> bayBeds = new List<string>(bayBedCollection.Split(new char[] { '|' }));

          // now we have the beds in the bay, so extract the bed properties and determine if the bed is male
          foreach(string bed in bayBeds) {
            string[] bedProperties = bed.Split(new char[] { '^' });
            if (bedProperties.Length > 1) {
              string genderCode = bedProperties[1];
              string bedStatus = bedProperties[2];
              if (genderCode == "M") {
                bedCount = bedCount + bayBeds.Count;
                break;

              }

            }

          }

        }

      } 

      return bedCount;

    }

这个函数接收一个以字符串形式表示的集合,格式如下:

100000^^3|100002^^1|100003^^3|100004^F^2|100005^^2@100006^^1|100007^^2|100008^M^2|100009^^1|100010^^3@100011^M^2|100012^M^2|100013^M^1|100014^M^2|100015^M^1@100016^F^1|100017^^1|100018^F^1|100019^^1|100020^^1

然后将其分解成类似于这样的单元:
100000^^3|100002^^1|100003^^3|100004^F^2|100005^^2

它会进一步解析为类似于这样的单元:

100005^^2 or 100004^F^2

有时在这些迭代过程中,其中一个单位会返回畸形,并且长度为1,因此尝试获取一个大于0的索引将失败。

顺便说一下,这是一个变换内部的扩展方法,这就是以一个大字符串作为初始集合的原因。

感谢所有帮助过我的人 - 很抱歉我无法选择多个正确答案。


如果您总是访问 bedProperties[1],那么您应该检查 bedProperties.Length > 1 是否成立...这不可能存在 bayBeds 中有一张床只有一个属性而导致异常的情况吗? - fwalch
我知道你已经用粗体标出了两次,但是为了澄清 - 即使你知道数组有多于1个元素,你仍然会收到一个越界异常吗? - jball
@jball,传入的字符串看起来像这样:100000^^3或100004^F^2。每个字符串中始终有4个元素。 - Thomas W Tupper
快速更正,这两个都会产生三个元素的数组。可以假设下面答案中提出的任何更改都没有解决您的问题吗? - jball
@jball 是的,谢谢你的纠正 - 真是疯了,我居然说了那个。 - Thomas W Tupper
3个回答

5
if (bedProperties.Length > 0)

应该是:

if(bedProperties.Length > 1)

因为任何字符串在拆分时都会返回一个只有自己的单元素数组。如果真的进行了任何拆分,数组中将会有两个或更多元素。


你并不是真正了解那个。公平地说,我认为 OP 弄错了从零开始的索引更有可能(相比之下,像“长度”这样的绝对数量很难理解错误)。 - sehe
如果实际上是零索引问题,那么根本不需要进行if检查,因为对split的任何调用都至少有一个元素。 - Justin Niessner
OP 表示,直接检查数组的长度大于 1(例如 3),这表明问题不是由返回单个元素数组引起的。 - jball
[简单解释一下Justin的答案] 访问索引1意味着bedProperties中至少有2个项目(在索引0和1处)。因此,您需要检查bedProperties的长度/大小是否至少有两个项目(大于1)。 - geffchang
我更新了上面的问题,以提供答案的详细信息。这只是一个坏数据问题,也是我对C#的无知。非常感谢大家 - 希望我能向每个人致敬。 - Thomas W Tupper
显示剩余3条评论

5

您遇到了没有^字符的字符串:

要么修复索引:

if (bedProperties.Length > 0) {
  string genderCode = bedProperties[0]; // would take the **first** split element

或者是以下情况:
if (bedProperties.Length > 1) {
  string genderCode = bedProperties[1]; // would take the **second** split element

索引从零开始 !!)

(注意:感叹号要用中文符号)

你的第一行代码与 OP 的说法“我可以修改它以返回 bedProperties.Length,这将给我一个值,例如 3”有何关联? - jball
@jball:为什么不问问原帖作者呢?肯定不是用这段代码。再说了,这段代码也没有返回bedProperties.Length,所以那个时候可能还有其他不同的地方。 - sehe
让我们在聊天中继续这个讨论:http://chat.stackoverflow.com/rooms/5421/discussion-between-sehe-and-jball - sehe
实际上,@Sehe 你也是正确的- 数据元素格式不正确,并且不包含任何分隔符。真希望我也能给你一个正确答案。你和Justin基本上解决了同样的问题,但他先回答了,所以我标记了他的答案为正确的。不过我还是提高了你的评分。 - Thomas W Tupper
@ThomasWTupper:谢谢,这就是我们在这里的原因!记录一下,“give a correct”通常被称为“接受答案” :) - sehe

0
你测试了 if (bedProperties.Length > 0),但你正在访问 bedProperties[1]; 你应该检查 if (bedProperties.Length > 1) 来确保索引1可用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接