C # เทียบเท่าเวกเตอร์ C ++ ที่มีหน่วยความจำติดกัน?


87

C # เทียบเท่าเวกเตอร์ C ++ คืออะไร

ฉันกำลังค้นหาคุณสมบัตินี้:

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

ฉันกำลังค้นหาและพวกเขาก็พูดว่า.NET equivalent to the vector in C++ is the ArrayList:

ArrayList มีคุณสมบัติหน่วยความจำที่ต่อเนื่องกันหรือไม่?


4
CLR อยู่ใกล้กับโลหะไม่เพียงพอที่คุณจะระบุ (หรือคาดหวังอย่างสม่ำเสมอ) ว่าโครงสร้างถูกจัดสรรอย่างไรในหน่วยความจำ?
Aphex

คำตอบ:


104

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

ตัวอย่าง:

List<int> integers = new List<int>();
integers.Add(1);
integers.Add(4);
integers.Add(7);

int someElement = integers[1];

2
@cMinor เอกสารประกอบของList<T>ชั้นเรียนมีตัวอย่างมากมาย แต่ฉันได้อัปเดตคำตอบเพื่อรวมไว้ด้วย
Darin Dimitrov

5
ฉันไม่คุ้นเคยกับ CLR 100% แต่ก็สมเหตุสมผลดีที่แม้ว่าTจะเป็นประเภทอ้างอิงคุณก็ยังมีหน่วยความจำที่ต่อเนื่องกัน โดยพื้นฐานแล้วมันคือพอยน์เตอร์มากมาย ...
josaphatv

"ซึ่งจะไม่เป็นเช่นนั้นหาก T เป็นประเภทการอ้างอิง" - มันก็เหมือนกับT[]... OP ขอ "ไม่มีการลงโทษประสิทธิภาพสำหรับการเข้าถึงเทียบกับอาร์เรย์มาตรฐาน" และList<T>ระบุสิ่งนั้น และถ้าTเป็นประเภทการอ้างอิงก็จะคล้ายกับT*ใน C ++ ดังนั้นคุณจะได้รับความสัมพันธ์กันมากพอ ๆ กับใน C ++ หากใครต้องการให้วัตถุนั้นอยู่ติดกันแน่นอนว่าเราต้องการประเภทค่า ... ในทั้งสองภาษา แน่นอนความแตกต่างคือใน C ++ ทุกประเภทสามารถใช้เป็นค่าหรืออ้างอิงได้ในขณะที่ C # เป็นคุณสมบัติของประเภทผ่านความแตกต่างของคลาส / โครงสร้าง
Jim Balter

เรียนรู้บางสิ่งในวันนี้ ฉันคิดว่าList<T>มักจะใช้เป็นรายการที่เชื่อมโยงภายในเสมอ แล้วมันจะขยายแบบไดนามิกได้อย่างไรเมื่อเราเรียกAdd()? บางอย่างเช่น VB6 Redim Preserveที่ใช้ในการคัดลอกอาร์เรย์ทั้งหมดไปยังตำแหน่งใหม่?
dotNET

@dotNet List<T>สร้างอาร์เรย์ขนาดเล็กT[]ภายใน รายการภายในจะถูกเพิ่มลงในอาร์เรย์ เมื่อขนาดของอาร์เรย์เสร็จสมบูรณ์อาร์เรย์ใหม่จะถูกสร้างขึ้นเป็นสองเท่าของขนาดก่อนหน้า ข้อมูลจะถูกคัดลอกไปยังอาร์เรย์ใหม่ที่ใหญ่กว่าส่วนที่เล็กกว่าจะถูกทำลายและอื่น ๆ นักพัฒนาสามารถให้คำแนะนำที่จะ .NET เพื่อสร้างขนาดใหญ่ภายในอาร์เรย์เพียงพอก่อนที่จะกรอกผ่านคอนสตรัค:List new List<T>(expected_array_size)
Artru

16

ใช้List<T>. ภายในจะใช้อาร์เรย์และอาร์เรย์จะใช้หน่วยความจำที่ต่อเนื่องกัน


2
ไม่เป็นความจริงทั้งหมด ถ้า T เป็นประเภทการอ้างอิงจะไม่มีหน่วยความจำติดกัน
Matteo Mosca

2
@Matteo ถ้าคุณดูแหล่งที่มามี private T[] _items;ที่ใช้สำหรับการจัดเก็บแบ็กเอนด์ประเภทการอ้างอิงหรือไม่
บาลาร

13
ฉันรู้ดี แต่บอกฉัน. คุณมีรายการ <SomeClass> การอ้างอิงถึงอินสแตนซ์ SomeClass จะถูกเก็บไว้ในหน่วยความจำที่ต่อเนื่องกัน แต่จะไม่เก็บอินสแตนซ์เอง ในฐานะประเภทอ้างอิงพวกเขาจะอยู่ในกองและคุณก็รู้ว่าฮีปทำงานอย่างไร
มัตเตโอมอสกา

@MatteoMosca การจัดเก็บการอ้างอิงต่อเนื่องกันอย่างน้อยก็ลบระดับหนึ่งของทิศทาง ดีกว่าไม่มีอะไรฉันเดา
ทิม Seguine

7
@MatteoMosca OP ขอ "ไม่มีการลงโทษประสิทธิภาพสำหรับการเข้าถึงกับอาร์เรย์มาตรฐาน" นั่นเป็นความจริงของรายการ <T> ไม่ว่า T จะเป็นอย่างไรดังนั้นความคิดเห็นทั้งหมดของคุณในหน้านี้จึงไม่ตรงประเด็น
จิมบัลเตอร์

16

ครั้งแรกของทั้งหมดอยู่ห่างจากหรือArraylist Hashtableชั้นเรียนเหล่านี้จะถูกพิจารณาว่าเลิกใช้งานโดยสนับสนุนเรื่องยาสามัญ พวกเขายังคงใช้ภาษานี้เพื่อวัตถุประสงค์เดิม

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


15

C # มีประเภทอ้างอิงจำนวนมาก แม้ว่าตู้คอนเทนเนอร์จะจัดเก็บข้อมูลอ้างอิงไว้ติดๆกัน แต่สิ่งของเองก็อาจกระจัดกระจายไปตามกอง


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