Something About List<T>

Add vs AddRange, AutoAdd vs DefineAdd

SheenA
C# Programming Tips
2 min readOct 12, 2013

--

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

เรื่องแรกเลยคือการใช้ Add กับ AddRange

DemoList1

จากตัวอย่างโค้ดข้างบน ส่วนบนจะเป็นการใช้ AddRange ส่วนล่างจะเป็นการใช้งาน Add แบบธรรมดา ผลลัพธ์ที่ได้คือ

Result1

จะเห็นว่าจากการวนลูปค่า List<int> fillData โดยใช้ค่า 1-10000000 จะเห็นว่าแบบ AddRange เร็วกว่าแบบ Add ธรรมดาถึง 5.3 เท่า ยิ่งใช้ค่ามากขึ้นจำนวนเท่าก็จะยิ่งเพิ่มมากขึ้น สรุปคือ AddRange เร็วกว่า Add มาก

เรื่องต่อมา เรื่องที่สอง

ก่อนอื่นต้องออกตัวก่อนเลยว่าคำว่า AutoAdd กับ DefineAdd เป็นคำที่บรรญัติขึ้นมาเองเพื่อให้อ่านแล้วเข้าใจได้ง่าย สำหรับการใช้ List<T> ในการสร้าง object ขึ้นมา โดยการประกาศ List<T> lst = new List<T>(); ขึ้นมา Complier — ของ C# จะทำการสร้าง object ในแบบ Automatic List ขึ้นมาให้เรา 4 object และเมื่อมีการใส่ค่าเข้าไปใน List<T> เมื่อใกล้ครบ 4 object ก็จะทำการสร้างเพิ่มขึ้นมาให้อีกครั้ง 4 object เป็นอย่างนี้ไปเรื่อยๆ การทำแบบนี้ผมเรียกว่า AutoAdd

ส่วนการ Define คือการที่เรารู้จำนวนที่แน่นอนของ object ที่ต้องการใส่ค่าให้ List<T> โดยการประกาศ List<T> lst = new List<T>(Length); จะช่วยให้ Complier ทำงานได้เร็วขึ้นเนื่องจากไม่ต้องคอยสร้าง object ไปเรื่อยๆ แต่ทำการสร้างครั้งเดียว

DemoList2

จากโค้ดส่วนแรกเป็นการประกาศ List<T> ในแบบปกติที่เราคุ้นเคยหรือแบบประกาศนิยม ส่วนที่สองมีการกำหนดค่า fillData.Count เพื่อทำการระบุจำนวน object ที่ต้องการซึ่งผมเรียกว่า DefineAdd ผลลัพธ์ที่ได้คือ

Result2

สรุปได้ว่าแบบ DefineAdd เร็วกว่าแบบ AutoAdd

เรื่องสุดท้าย เรื่องแถม

เรื่องนี้เกิดจากความเผลอของผมเอง โดยปกติแล้วเมื่อเราประกาศ List<T> ขึ้นมาแล้วต้องการนำค่าจาก List<T> a ไปใส่ให้ List<T> b เพื่อเก็บค่าไว้ชั่วคราว แต่ความสะเพร่าของผมก็เผลอ ไปเขียน List<T> b = a; คราวซวยก็เริ่มบังเกิด แต่โชคดีผมไหวตัวทันนึกย้อนไปสมัยเรียนก็จำขึ้นมาได้ว่าหากต้องการ นำค่าจาก List<T> a ไปใส่ไว้ ที่ List<T> b ต้องเขียนแบบนี้คือ List<T> b = new List<T>(a); หรือประกาศ List<T> b แล้วใช้ b.AddRange(a); ถึงจะถูกต้อง

ทีนี้เราลองมาดูกันว่าทำไม

DemoList3

จากโค้ดผมกำหนดค่าให้ List<int> ไป 10 ค่า จากนั้นผมทำการให้ List<int> d = a; และทำการ Remove ค่าตัวที่ 10 ออกไป ผลลัพธ์ที่ได้คือ

ค่า a ตัวที่ 10 หายไปด้วย สรุปคือการเขียนแบบนี้เป็นเพียงการชี้ไปที่ที่อยู่ของ a ไม่ใช่การชี้ไปที่ค่า a หรือกำหนดค่า d ให้เท่ากับ a

See you in Medium next time……….enjoy with your code

--

--

SheenA
C# Programming Tips

I have no idea...Application Developer/IT/Social/Politics/Philosophy/Ecotourism...& Blah Blah Blah