ฉันควรใช้รายการหรืออาเรย์


22

ฉันกำลังทำงานบนฟอร์ม windows เพื่อคำนวณ UPC สำหรับหมายเลขรายการ

ฉันประสบความสำเร็จในการสร้างหมายเลขที่จะจัดการหมายเลขรายการ / UPC ทีละรายการตอนนี้ฉันต้องการขยายและทำสำหรับหลายรายการหมายเลข / UPCs

ฉันเริ่มและลองใช้รายการ แต่ฉันยังคงติดอยู่ ฉันสร้างคลาสผู้ช่วยเหลือ:

public class Codes
{
    private string incrementedNumber;
    private string checkDigit;
    private string wholeNumber;
    private string wholeCodeNumber;
    private string itemNumber;

    public Codes(string itemNumber, string incrementedNumber, string checkDigit, string wholeNumber, string wholeCodeNumber)
    {
        this.incrementedNumber = incrementedNumber;
        this.checkDigit = checkDigit;
        this.wholeNumber = wholeNumber;
        this.wholeCodeNumber = wholeCodeNumber;
        this.itemNumber = itemNumber;
    }

    public string ItemNumber
    {
        get { return itemNumber; }
        set { itemNumber = value; }
    }

    public string IncrementedNumber
    { 
        get { return incrementedNumber; }
        set { incrementedNumber = value; } 
    }

    public string CheckDigit
    {
        get { return checkDigit; }
        set { checkDigit = value; }
    }

    public string WholeNumber
    {
        get { return wholeNumber; }
        set { wholeNumber = value; }
    }

    public string WholeCodeNumber
    {
        get { return wholeCodeNumber; }
        set { wholeCodeNumber = value; }
    }

}

จากนั้นฉันก็เริ่มใช้รหัสของฉัน แต่ปัญหาคือกระบวนการเพิ่มขึ้นนั่นหมายถึงฉันได้รับหมายเลขรายการจาก gridview ผ่านช่องทำเครื่องหมายและใส่ไว้ในรายการ จากนั้นฉันจะได้รับ UPC ล่าสุดจากฐานข้อมูลดึงแถบตรวจสอบออกจากนั้นเพิ่มตัวเลขทีละหนึ่งและใส่ไว้ในรายการ จากนั้นฉันคำนวณ checkdigit สำหรับหมายเลขใหม่และใส่ไว้ในรายการ และที่นี่ฉันได้รับข้อยกเว้นความจำหมดแล้ว นี่คือรหัสที่ฉันมี:

List<Codes> ItemNumberList = new List<Codes>();


    private void buttonSearch2_Click(object sender, EventArgs e)
    {
        //Fill the datasets
        this.immasterTableAdapter.FillByWildcard(this.alereDataSet.immaster, (textBox5.Text));
        this.upccodeTableAdapter.FillByWildcard(this.hangtagDataSet.upccode, (textBox5.Text));
        this.uPCTableAdapter.Fill(this.uPCDataSet.UPC);
        string searchFor = textBox5.Text;
        int results = 0;
        DataRow[] returnedRows;
        returnedRows = uPCDataSet.Tables["UPC"].Select("ItemNumber = '" + searchFor + "2'");
        results = returnedRows.Length;
        if (results > 0)
        {
            MessageBox.Show("This item number already exists!");
            textBox5.Clear();
            //clearGrids();
        }
        else
        {
            //textBox4.Text = dataGridView1.Rows[0].Cells[1].Value.ToString();
            MessageBox.Show("Item number is unique.");
        }
    }

    public void checkMarks()
    {

        for (int i = 0; i < dataGridView7.Rows.Count; i++)
        {
            if ((bool)dataGridView7.Rows[i].Cells[3].FormattedValue)
            {
                {
                    ItemNumberList.Add(new Codes(dataGridView7.Rows[i].Cells[0].Value.ToString(), "", "", "", ""));
                }
            }
        }
    }

    public void multiValue1()
    {
        _value = uPCDataSet.UPC.Rows[uPCDataSet.UPC.Rows.Count - 1]["UPCNumber"].ToString();//get last UPC from database
        _UPCNumber = _value.Substring(0, 11);//strip out the check-digit
        _UPCNumberInc = Convert.ToInt64(_UPCNumber);//convert the value to a number

        for (int i = 0; i < ItemNumberList.Count; i++)
        {
            _UPCNumberInc = _UPCNumberInc + 1;
            _UPCNumberIncrement = Convert.ToString(_UPCNumberInc);//assign the incremented value to a new variable
            ItemNumberList.Add(new Codes("", _UPCNumberIncrement, "", "", ""));//**here I get the OutOfMemoreyException**
        }

        for (int i = 0; i < ItemNumberList.Count; i++)
        {
            long chkDigitOdd;
            long chkDigitEven;
            long chkDigitSubtotal;
            chkDigitOdd = Convert.ToInt64(_UPCNumberIncrement.Substring(0, 1)) + Convert.ToInt64(_UPCNumberIncrement.Substring(2, 1)) + Convert.ToInt64(_UPCNumberIncrement.Substring(4, 1)) + Convert.ToInt64(_UPCNumberIncrement.Substring(6, 1)) + Convert.ToInt64(_UPCNumberIncrement.Substring(8, 1)) + Convert.ToInt64(_UPCNumberIncrement.Substring(10, 1));
            chkDigitOdd = (3 * chkDigitOdd);
            chkDigitEven = Convert.ToInt64(_UPCNumberIncrement.Substring(1, 1)) + Convert.ToInt64(_UPCNumberIncrement.Substring(3, 1)) + Convert.ToInt64(_UPCNumberIncrement.Substring(5, 1)) + Convert.ToInt64(_UPCNumberIncrement.Substring(7, 1)) + Convert.ToInt64(_UPCNumberIncrement.Substring(9, 1));
            chkDigitSubtotal = (300 - (chkDigitEven + chkDigitOdd));
            _chkDigit = chkDigitSubtotal.ToString();
            _chkDigit = _chkDigit.Substring(_chkDigit.Length - 1, 1);
            ItemNumberList.Add(new Codes("", "",_chkDigit, "", ""));
        }

นี่เป็นวิธีที่ถูกต้องหรือไม่ที่จะใช้รายการหรือฉันควรจะมองไปทางอื่นหรือไม่?


ใช้รายการได้ดี การวนซ้ำรายการในขณะที่เพิ่มเข้าไปเป็นวิธีที่แน่นอนในการระเบิดรหัสของคุณและระบุปัญหาในตรรกะของคุณ (หรือการเขียนโค้ด) นอกจากนี้นี่เป็นข้อบกพร่องของคุณและไม่น่าจะช่วยผู้เยี่ยมชมในอนาคต การลงคะแนนให้ปิด
Telastyn

2
ในฐานะที่เป็นบันทึกด้านข้างสนามส่วนตัวเหล่านี้ (ในCodeชั้นเรียนของคุณ) ซ้ำซ้อนและไม่มีอะไรนอกจากเสียงรบกวนจริง ๆ{ get; private set; }จะเพียงพอ
Konrad Morawski

5
ชื่อคำถามสำหรับสิ่งนี้ถูกต้องจริงเหรอ? ดูเหมือนว่านี่จะไม่ใช่คำถามรายการเทียบกับอาร์เรย์มากเท่าฉันจะปรับปรุงคำถามการใช้งานได้อย่างไร ถ้าคุณกำลังเพิ่มหรือลบองค์ประกอบคุณต้องการรายการ (หรือโครงสร้างข้อมูลที่ยืดหยุ่นอื่น ๆ ) อาร์เรย์จะดีมากเมื่อคุณรู้จำนวนองค์ประกอบที่คุณต้องการในตอนเริ่มต้นเท่านั้น
KChaloux

@Kalhaoux นั่นเป็นสิ่งที่ฉันอยากรู้ รายการเป็นวิธีที่เหมาะสมที่จะไปเกี่ยวกับเรื่องนี้หรือฉันควรจะดูวิธีอื่นในการติดตามเรื่องนี้หรือไม่? ดังนั้นรายการดูเหมือนจะเป็นวิธีที่ดีฉันต้องปรับตรรกะของฉัน
campagnolo_1

1
@Telastyn ฉันไม่ได้ขอให้ปรับปรุงโค้ดของฉันมากนักเพื่อแสดงสิ่งที่ฉันพยายามจะทำ
campagnolo_1

คำตอบ:


73

ฉันจะขยายความคิดเห็นของฉัน:

... หากคุณกำลังเพิ่มหรือลบองค์ประกอบคุณต้องการรายการ (หรือโครงสร้างข้อมูลที่ยืดหยุ่นอื่น ๆ ) อาเรย์นั้นดีมากเมื่อคุณรู้จำนวนองค์ประกอบที่คุณต้องการในตอนเริ่มต้น

รายละเอียดด่วน

อาร์เรย์เป็นสิ่งที่ดีเมื่อคุณมีองค์ประกอบจำนวนหนึ่งซึ่งไม่น่าจะเปลี่ยนแปลงได้และคุณต้องการเข้าถึงมันในลักษณะที่ไม่ต่อเนื่อง

  • ขนาดคงที่
  • การเข้าถึงที่รวดเร็ว - O (1)
  • Slow Resize - O (n) - ต้องการคัดลอกทุกองค์ประกอบไปยังอาร์เรย์ใหม่!

รายการที่เชื่อมโยงได้รับการปรับให้เหมาะสมสำหรับการเพิ่มและลบอย่างรวดเร็วที่ปลายทั้งสอง แต่จะเข้าถึงได้ช้าในตรงกลาง

  • ขนาดตัวแปร
  • เข้าถึงช้าที่ตรงกลาง - O (n)
    • ต้องการสำรวจแต่ละองค์ประกอบที่เริ่มต้นจากส่วนหัวเพื่อเข้าถึงดัชนีที่ต้องการ
  • เข้าถึงได้อย่างรวดเร็วที่หัว - O (1)
  • การเข้าถึงที่รวดเร็วที่หาง
    • O (1) ถ้าการอ้างอิงถูกเก็บไว้ที่ส่วนท้าย (เช่นเดียวกับรายการที่เชื่อมโยงเป็นสองเท่า)
    • O (n) หากไม่มีการจัดเก็บการอ้างอิง (ความซับซ้อนเช่นเดียวกับการเข้าถึงโหนดที่อยู่ตรงกลาง)

รายการอาร์เรย์ (เช่นList<T>ใน C #!) เป็นส่วนผสมของสองรายการพร้อมการเพิ่มที่รวดเร็วและการเข้าถึงแบบสุ่ม List<T> มักจะเป็นคอลเลกชันของคุณไปเมื่อคุณไม่แน่ใจว่าจะใช้อะไร

  • ใช้อาร์เรย์เป็นโครงสร้างสำรอง
  • ฉลาดมากเกี่ยวกับการปรับขนาด - จัดสรรสองเท่าของพื้นที่ปัจจุบันเมื่อมันหมด
    • สิ่งนี้นำไปสู่การปรับขนาด O (log n) ซึ่งดีกว่าการปรับขนาดทุกครั้งที่เราเพิ่ม / ลบ
  • การเข้าถึงที่รวดเร็ว - O (1)

วิธีการทำงานของอาร์เรย์

โมเดลภาษาส่วนใหญ่จะใช้อาร์เรย์เป็นข้อมูลที่ต่อเนื่องกันในหน่วยความจำซึ่งแต่ละองค์ประกอบมีขนาดเท่ากัน สมมติว่าเรามีอาร์เรย์ints (แสดงเป็น [ที่อยู่: ค่า] โดยใช้ที่อยู่ทศนิยมเพราะฉันขี้เกียจ)

[0: 10][32: 20][64: 30][96: 40][128: 50][160: 60]

องค์ประกอบเหล่านี้แต่ละรายการเป็นจำนวนเต็ม 32 บิตดังนั้นเราจึงรู้ว่าต้องใช้เนื้อที่เท่าใดในหน่วยความจำ (32 บิต!) และเรารู้ที่อยู่หน่วยความจำของตัวชี้ไปยังองค์ประกอบแรก

มันง่ายมากที่จะได้ค่าขององค์ประกอบอื่น ๆ ในอาร์เรย์นั้น:

  • จดที่อยู่ขององค์ประกอบแรก
  • ใช้ออฟเซ็ตของแต่ละองค์ประกอบ (ขนาดในหน่วยความจำ)
  • คูณออฟเซ็ตด้วยดัชนีที่ต้องการ
  • เพิ่มผลลัพธ์ของคุณไปยังที่อยู่ขององค์ประกอบแรก

สมมติว่าองค์ประกอบแรกของเราอยู่ที่ '0' เรารู้ว่าองค์ประกอบที่สองของเราอยู่ที่ '32' (0 + (32 * 1)) และองค์ประกอบที่สามของเราอยู่ที่ 64 (0 + (32 * 2))

ความจริงที่ว่าเราสามารถเก็บค่าเหล่านี้ทั้งหมดไว้ข้าง ๆ กันในหน่วยความจำหมายความว่าอาร์เรย์ของเรามีขนาดกะทัดรัดที่สุดเท่าที่จะเป็นไปได้ นอกจากนี้ยังหมายความว่าองค์ประกอบทั้งหมดของเราจำเป็นต้องอยู่ด้วยกันเพื่อให้สิ่งต่าง ๆ ทำงานต่อไป!

ทันทีที่เราเพิ่มหรือลบองค์ประกอบเราต้องรับทุกอย่างและคัดลอกไปยังที่ใหม่ในหน่วยความจำเพื่อให้แน่ใจว่าไม่มีช่องว่างระหว่างองค์ประกอบและทุกอย่างมีที่ว่างเพียงพอ นี้อาจจะช้ามาก , โดยเฉพาะอย่างยิ่งถ้าคุณกำลังทำมันทุกครั้งที่คุณต้องการที่จะเพิ่มองค์ประกอบเดียว

รายการที่เชื่อมโยง

รายการที่เชื่อมโยงไม่จำเป็นต้องมีองค์ประกอบทั้งหมดที่อยู่ติดกันในหน่วยความจำ ประกอบด้วยโหนดที่เก็บข้อมูลต่อไปนี้:

Node<T> {
    Value : T      // Value of this element in the list
    Next : Node<T> // Reference to the node that comes next
}

รายการนั้นจะอ้างอิงถึงส่วนหัวและส่วนท้าย (โหนดแรกและโหนดสุดท้าย) ในกรณีส่วนใหญ่และบางครั้งจะติดตามขนาดของมัน

หากคุณต้องการที่จะเพิ่มองค์ประกอบในตอนท้ายของรายการทั้งหมดที่คุณต้องทำคือการได้รับหางและเปลี่ยนNextเป็นการอ้างอิงใหม่Nodeที่มีค่าของคุณ การลบออกจากจุดสิ้นสุดนั้นง่ายพอ ๆ กัน - เพียงพิจารณาNextค่าของโหนดก่อนหน้านี้

น่าเสียดายถ้าคุณมีLinkedList<T>องค์ประกอบ 1,000 รายการและคุณต้องการองค์ประกอบ 500 ไม่มีวิธีที่ง่ายในการข้ามไปทางขวาไปยังองค์ประกอบที่ 500 เช่นเดียวกับที่มีอาร์เรย์ คุณต้องเริ่มที่หัวและไปยังNextโหนดต่อไปจนกว่าคุณจะทำเสร็จ 500 ครั้ง

นี่คือสาเหตุที่การเพิ่มและลบออกจาก LinkedList<T>รวดเร็ว (เมื่อทำงานที่ปลาย) แต่การเข้าถึงตรงกลางนั้นช้า

แก้ไข : ไบรอันชี้ให้เห็นในความคิดเห็นว่ารายการที่เชื่อมโยงมีความเสี่ยงที่จะทำให้เกิดความผิดพลาดของหน้าเนื่องจากไม่ถูกจัดเก็บในหน่วยความจำต่อเนื่อง สิ่งนี้อาจเป็นเรื่องยากที่จะวัดประสิทธิภาพและสามารถสร้างรายการที่เชื่อมโยงได้ช้ากว่าที่คุณคาดหวังเนื่องจากความซับซ้อนของเวลา

สุดยอดของทั้งสองโลก

List<T> ประนีประนอมทั้ง T[]และLinkedList<T>และมาพร้อมกับโซลูชันที่สมเหตุสมผลและใช้งานง่ายในสถานการณ์ส่วนใหญ่

ภายใน List<T>คืออาเรย์! มันยังคงต้องกระโดดผ่านห่วงของการคัดลอกองค์ประกอบเมื่อปรับขนาด แต่ดึงเทคนิคบางอย่างเรียบร้อย

สำหรับผู้เริ่มต้นการเพิ่มองค์ประกอบเดียวมักไม่ทำให้อาร์เรย์คัดลอก List<T>ทำให้แน่ใจว่ามีที่ว่างเพียงพอสำหรับองค์ประกอบเพิ่มเติม เมื่อมันหมดแทนที่จะจัดสรรอาเรย์ภายในใหม่ที่มีองค์ประกอบใหม่เพียงอันเดียวมันจะจัดสรรอาเรย์ใหม่ที่มีหลายองค์ประกอบองค์ประกอบใหม่อย่าง

การทำสำเนามีราคาแพงมาก List<T>ลดจำนวนพวกมันให้มากที่สุดเท่าที่จะเป็นไปได้ในขณะที่ยังสามารถเข้าถึงแบบสุ่มได้อย่างรวดเร็ว ในฐานะที่เป็นผลข้างเคียงมันอาจจะสิ้นเปลืองพื้นที่มากขึ้นกว่าอาร์เรย์แบบตรงหรือรายการที่เชื่อมโยงเล็กน้อย แต่โดยทั่วไปแล้วมันจะคุ้มค่ากับการแลกเปลี่ยน

TL; DR

List<T>ใช้ ปกติแล้วเป็นสิ่งที่คุณต้องการและดูเหมือนว่าจะถูกต้องสำหรับคุณในสถานการณ์นี้ (ที่คุณกำลังโทรหา. เพิ่ม ()) หากคุณไม่แน่ใจในสิ่งที่คุณต้องการList<T>เป็นจุดเริ่มต้นที่ดี

อาร์เรย์เป็นสิ่งที่ดีสำหรับประสิทธิภาพสูง "ฉันรู้ว่าฉันต้องการองค์ประกอบ X อย่างแน่นอน" อีกทางเลือกหนึ่งคือพวกมันมีประโยชน์สำหรับการออกครั้งเดียวอย่างรวดเร็ว "ฉันต้องการจัดกลุ่มสิ่ง X เหล่านี้ที่ฉันได้กำหนดไว้แล้วเพื่อให้ฉันสามารถวนรอบสิ่งเหล่านี้ได้"

มีคลาสคอลเล็กชันอื่นจำนวนมาก Stack<T>เหมือนรายการที่เชื่อมโยงซึ่งทำงานจากด้านบนเท่านั้น Queue<T>ทำงานเป็นรายการเข้าก่อนออกก่อน Dictionary<T, U>คือการแมปที่ไม่ได้เรียงลำดับการเชื่อมโยงระหว่างคีย์และค่า เล่นกับพวกเขาและทำความรู้จักจุดแข็งและจุดอ่อนของแต่ละคน พวกเขาสามารถสร้างหรือทำลายอัลกอริทึมของคุณ


2
ในบางกรณีอาจมีข้อได้เปรียบในการใช้การรวมกันของอาร์เรย์และการintระบุจำนวนองค์ประกอบที่ใช้งานได้ เหนือสิ่งอื่นใดก็เป็นไปได้ที่จะคัดลอกหลายองค์ประกอบจากอาร์เรย์หนึ่งไปยังอีก แต่การคัดลอกระหว่างรายการโดยทั่วไปต้องใช้องค์ประกอบการประมวลผลเป็นรายบุคคล นอกจากนี้องค์ประกอบอาร์เรย์อาจถูกส่งผ่านrefไปยังสิ่งต่าง ๆ เช่นInterlocked.CompareExchangeในขณะที่รายการไม่สามารถ
supercat

2
ฉันหวังว่าฉันจะสามารถโหวตได้มากกว่าหนึ่งครั้ง ฉันรู้ถึงความแตกต่างในการใช้งานและวิธีการทำงานของอาร์เรย์ / รายการที่เชื่อมโยง แต่ฉันไม่เคยรู้หรือคิดเกี่ยวกับวิธีการList<>ทำงานของฝากระโปรง
Bobson

1
การเพิ่มองค์ประกอบเดียวในรายการ <T> จะถูกตัดจำหน่าย O (1); ประสิทธิภาพของการเพิ่มองค์ประกอบนั้นโดยปกติจะไม่เพียงพอเหตุผลที่จะใช้รายการที่เชื่อมโยง (และรายชื่อแบบวงกลมช่วยให้คุณสามารถเพิ่มไปข้างหน้าและกลับใน O ตัดจำหน่าย (1)) รายการที่เชื่อมโยงนั้นมีความเป็นไปได้มากมาย ตัวอย่างเช่นการไม่ถูกจัดเก็บอย่างต่อเนื่องในหน่วยความจำหมายความว่าการวนซ้ำในรายการที่เชื่อมโยงทั้งหมดมีแนวโน้มที่จะทริกเกอร์ข้อผิดพลาดของหน้า ... และนี่เป็นเกณฑ์มาตรฐานที่ยาก เหตุผลที่ใหญ่กว่าสำหรับการใช้รายการที่เชื่อมโยงคือเมื่อคุณต้องการเชื่อมโยงสองรายการ (สามารถทำได้ใน O (1)) หรือเพิ่มองค์ประกอบตรงกลาง
ไบรอัน

1
ฉันควรชี้แจง เมื่อฉันพูดถึงรายการแบบวงกลมฉันหมายถึงรายการอาร์เรย์แบบวงกลมไม่ใช่รายการแบบเชื่อมโยงแบบวงกลม คำที่ถูกต้องจะเป็น deque (คิวสองครั้ง) พวกมันมักจะถูกนำไปใช้ในลักษณะเดียวกับ List (array ภายใต้ hood) โดยมีข้อยกเว้นหนึ่งประการ: มีค่าจำนวนเต็มภายในคือ "first" ซึ่งระบุว่าดัชนีของอาร์เรย์ใดเป็นองค์ประกอบแรก ในการเพิ่มองค์ประกอบทางด้านหลังคุณเพียงแค่ลบ 1 จาก "แรก" (ล้อมไปตามความยาวของอาร์เรย์ถ้าจำเป็น) (index+first)%lengthในการเข้าถึงองค์ประกอบคุณเพียงแค่การเข้าถึง
ไบรอัน

2
มีบางสิ่งที่คุณไม่สามารถทำได้ด้วย List ซึ่งคุณสามารถทำได้กับ array แบบธรรมดาตัวอย่างเช่นการส่งอิลิเมนต์ดัชนีเป็นพารามิเตอร์ ref
เอียนโกลด์บาย

6

ในขณะที่คำตอบของ KChalouxนั้นยอดเยี่ยมฉันอยากจะชี้ให้เห็นการพิจารณาอื่น: List<T>มีประสิทธิภาพมากกว่า Array วิธีการของList<T>นั้นมีประโยชน์มากในหลาย ๆ สถานการณ์ - อาเรย์ไม่มีวิธีการเหล่านี้และคุณอาจใช้เวลามากในการดำเนินการแก้ไขปัญหา

ดังนั้นจากมุมมองการพัฒนาที่ฉันมักจะใช้List<T>เพราะเมื่อมีข้อกำหนดเพิ่มเติมพวกเขามักจะใช้งานง่ายกว่าเมื่อคุณใช้List<T>เพราะเมื่อมีความต้องการเพิ่มเติมพวกเขามักจะไกลได้ง่ายขึ้นในการดำเนินการเมื่อคุณกำลังใช้

สิ่งนี้นำไปสู่ปัญหาขั้นสุดท้าย: รหัสของฉัน (ฉันไม่รู้เกี่ยวกับคุณ) มี 90% List<T>ดังนั้นอาร์เรย์จึงไม่เหมาะสมจริง ๆ เมื่อฉันส่งพวกเขาไปรอบ ๆ ฉันต้องเรียก.toList()วิธีการของพวกเขาและแปลงเป็นรายการ - นี่คือ น่ารำคาญและช้ามากที่ประสิทธิภาพใด ๆ ที่เกิดขึ้นจากการใช้ Array จะสูญหายไป


เป็นจริงนี่เป็นอีกเหตุผลที่ดีที่จะใช้ List <T> - มันมีฟังก์ชั่นเพิ่มเติมมากมายสำหรับคุณที่สร้างไว้ในชั้นเรียนโดยตรง
KChaloux

1
LINQ ไม่ปรับระดับเขตข้อมูลด้วยการเพิ่มฟังก์ชันการทำงานจำนวนมากสำหรับ IEnumerable ใด ๆ (รวมถึงอาร์เรย์) มีอะไรเหลืออยู่ใน C # (4+) รุ่นใหม่ที่คุณสามารถทำได้ด้วย List <T> เท่านั้นและไม่ใช่อาร์เรย์?
เดฟ

1
@Dave การขยาย Array / List ดูเหมือนจะเป็นเรื่องแบบนี้ นอกจากนี้ฉันจะบอกว่าไวยากรณ์ในการสร้าง / จัดการรายการนั้นดีกว่าสำหรับอาร์เรย์
คริสเตียนซาวเออร์

2

ไม่มีใครพูดถึงส่วนนี้: "และที่นี่ฉันได้รับการยกเว้นหน่วยความจำแล้ว" ซึ่งเป็นเพราะ

for (int i = 0; i < ItemNumberList.Count; i++)
{
    ItemNumberList.Add(new item());
}

มันธรรมดาที่จะเห็นว่าทำไม ฉันไม่รู้ว่าคุณตั้งใจจะเพิ่มไปยังรายการอื่นหรือควรเก็บไว้ItemNumberList.Countเป็นตัวแปรก่อนลูปเพื่อให้ได้ผลลัพธ์ที่คุณต้องการ แต่นี่มันเสียง่าย

Programmers.SE สำหรับ "... สนใจในคำถามเชิงแนวคิดเกี่ยวกับการพัฒนาซอฟต์แวร์ ... " และคำตอบอื่น ๆ ถือว่าเป็นเช่นนั้น ลองhttp://codereview.stackexchange.comแทนซึ่งคำถามนี้จะพอดี แต่ถึงอย่างนั้นมันก็น่ากลัวเพราะเราสามารถสันนิษฐานได้ว่าโค้ดนี้เริ่มต้นที่_Clickซึ่งไม่มีการเรียกไปยังmultiValue1จุดที่คุณพูดว่าเกิดข้อผิดพลาดขึ้น

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.