简体   繁体   English

c#数组-索引超出范围异常

[英]c# Arrays - Index Out of Range Exception

I am getting indexoutofrangeexception (see ----> pointer for the line generating the error down below in the code). 我正在获取indexoutofrangeexception(在代码下面的向下生成错误的行,请参阅---->指针)。 The program loops through the header and line item records in a dataset tables. 该程序循环浏览数据集表中的标题和行项目记录。 The tables have a relationship. 这些表有关系。 My sample data has 2 headers, each with 2 lines. 我的样本数据有2个标题,每个标题有2行。 The progam has two loops, the first one loops through the header records and the second one loops through the child records of the header. 程序有两个循环,第一个循环遍历标题记录,第二个循环遍历标题的子记录。

Part of the program: 该程序的一部分:

     // ***** PO Header and Line 

        int ln;
        ln = 0;

        // Create an eConnect PO Header node object
        taGLTransactionHeaderInsert jeh = new taGLTransactionHeaderInsert();

        // Create an array for lineitems
        taGLTransactionLineInsert_ItemsTaGLTransactionLineInsert[] lineitems = new   taGLTransactionLineInsert_ItemsTaGLTransactionLineInsert[ln];

        foreach (DataRow dtrHDR in ds.Tables["Header"].Rows)

        {
            Array.Clear(lineitems, 0, ln);

            jeh.BACHNUMB = "Sheraz";
            jeh.JRNENTRY = jenoint;
            jeh.REFRENCE = dtrHDR["Reference"].ToString();
            jeh.SOURCDOC = dtrHDR["AvantisJE"].ToString();
            jeh.USERID = System.Environment.UserName;
            jeh.TRXDATE = System.DateTime.Now.ToString();

            ln = 0;

            foreach (DataRow dtrLine in dtrHDR.GetChildRows("HdrLine"))

            {

                // Populate the elements of the taPoLIne_ItemsTaPOLine XML node
                taGLTransactionLineInsert_ItemsTaGLTransactionLineInsert jel = new taGLTransactionLineInsert_ItemsTaGLTransactionLineInsert();

                jel.BACHNUMB = jeh.BACHNUMB;
                jel.JRNENTRY = jeh.JRNENTRY;
                jel.ACTNUMST = dtrLine["GreatPlains"].ToString();
                jel.DEBITAMT = Convert.ToDecimal(dtrLine["Debit"].ToString());

                //Avantis Inv Trx Key
                jel.ORDOCNUM = dtrLine["AvantisJE_Line"].ToString();
                // Avantis GL Trx Type
                jel.ORTRXDESC = dtrLine["transactiontypename"].ToString();


                //Add POLine to an Array
                lineitems[ln] = jel;     ----------------> I get an error here!

                ln = ln + 1;

                Array.Resize(ref lineitems, ln + 1);

            }

        }

This is because you created an array with 0 elements and try to insert an element on position 0. This will not work. 这是因为您创建了一个包含0个元素的数组,并尝试在位置0处插入一个元素。这将不起作用。 You can fix it by declaring the array with a size of 1 to begin with: 您可以通过声明大小为1的数组开头来解决此问题:

// Create an array for lineitems
taGLTransactionLineInsert_ItemsTaGLTransactionLineInsert[] lineitems = new   taGLTransactionLineInsert_ItemsTaGLTransactionLineInsert[1];

However, resizing an array on the fly is not the idiomatic .NET way of doing this. 但是,动态调整数组大小并不是.NET惯用的方式。 You could use a List<T> , which takes care of resizing for you, and leaving you with cleaner code and possibly better performance. 您可以使用List<T> ,它可以为您调整大小,并为您提供更简洁的代码和可能更好的性能。

You are accessing an index that doesn't yet exist. 您正在访问尚不存在的索引。

//Add POLine to an Array
lineitems[ln] = jel;     ----------------> I get an error here!
ln = ln + 1;     
Array.Resize(ref lineitems, ln + 1);

You need to change the order to : 您需要将订单更改为:

//Add POLine to an Array
Array.Resize(ref lineitems, ln + 1);
lineitems[ln] = jel;     ----------------> should be fixed, no error here!
ln = ln + 1;     

EDIT: Now that the immediate problem is out of the way, on to a better implementation. 编辑:现在,眼前的问题已经解决,可以进行更好的实施了。

Arrays are of a fixed sized, resizing an array is an expensive operation (basically it entails creating a copy with a new size). 数组大小固定,调整数组大小是一项昂贵的操作(基本上,它需要创建一个新大小的副本)。 typically you would use these after identifying a performance bottle neck. 通常,您需要在确定性能瓶颈后使用它们。 In most cases it would be much better to use a List. 在大多数情况下,使用列表会更好。

I'd recommend changing this line: 我建议更改此行:

// Create an array for lineitems
taGLTransactionLineInsert_ItemsTaGLTransactionLineInsert[] lineitems = 
              new    taGLTransactionLineInsert_ItemsTaGLTransactionLineInsert[ln];

to: 至:

var lineitems = new  List<taGLTransactionLineInsert_ItemsTaGLTransactionLineInsert>();

and then to add to it you simply do 然后添加到它,您只需

lineitems.Add(jel);

to iterate over them would be: 对它们进行迭代将是:

for (var ln in lineitems) {
 // whatever you want to do with a line.
}

to acccess a specific item by index would be: 按索引访问特定项目的方法是:

lineitems.Item(i); // get the ith item in the list.

It appears that you're trying to increase the size of the array by setting a value, like you might do in JavaScript. 似乎您正在尝试通过设置值来增加数组的大小,就像在JavaScript中那样。 C# arrays are not like that. C#数组不是那样的。 You need to create them at the size you want them to be when finished. 您需要以完成后所需的尺寸创建它们。

Alternately, you could use a List object, using the Add() method to put new content into the list. 或者,您可以使用List对象,并使用Add()方法将新内容放入列表中。

lineitems is obviously not the same size as the row collection returned by dtrHDR.GetChildRows("HdrLine") . lineitems的大小显然与dtrHDR.GetChildRows("HdrLine")返回的行集合的大小不同。 You are creating an array of zero elements and then trying to index into it. 您正在创建一个零元素数组,然后尝试对其进行索引。 If you want it to match the size of dtrHDR.GetChildRows("HdrLine") then you need to call that first and initialize the array after you can get the count. 如果希望它与dtrHDR.GetChildRows("HdrLine")的大小匹配,则需要先调用它,然后在获得计数后初始化数组。

Instead of using an array why don't you use a List<T> and just push items onto it? 为什么不使用List<T>而不是使用数组,而只是将项目压入其中? No need to worry about IndexOutOfRange exceptions anymore. 不再需要担心IndexOutOfRange异常。

You need to initialize the array before putting anything in to it. 您需要先对数组进行初始化,然后再将其放入其中。 call the .resize first. 首先调用.resize。

those lines are the problem 这些线是问题

 int ln;
 ln = 0;

 // Create an array for lineitems
 taGLTransactionLineInsert_ItemsTaGLTransactionLineInsert[] lineitems = new   taGLTransactionLineInsert_ItemsTaGLTransactionLineInsert[ln];

You create table of 0 elements. 您创建的表包含0个元素。

You have an off-by-one error in your program: 您的程序中出现一个错误的错误:

    int ln = 0
    .
    .
    .
    taGLTransactionLineInsert_ItemsTaGLTransactionLineInsert[] lineitems = new   taGLTransactionLineInsert_ItemsTaGLTransactionLineInsert[ln];
    .
    .
    .
    lineitems[ln] = jel;

You are initializing an array of 0 elements, then trying to set the first element (element[0]) to a value. 您正在初始化一个由0个元素组成的数组,然后尝试将第一个元素(element [0])设置为一个值。

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

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