เหตุใด IList จึงไม่รองรับ AddRange


91

List.AddRange()มีอยู่ แต่IList.AddRange()ไม่มี
สิ่งนี้ทำให้ฉันประหลาดใจ เหตุผลเบื้องหลังนี้คืออะไร?

คำตอบ:


69

เนื่องจากอินเทอร์เฟซ shoud ใช้งานง่ายและไม่มี "ทุกอย่างยกเว้นห้องครัว" หากคุณเพิ่มAddRangeคุณควรเพิ่มInsertRangeและRemoveRange(สำหรับสมมาตร) คำถามที่ดีกว่าคือทำไมไม่มีวิธีการขยายสำหรับIList<T>อินเทอร์เฟซที่คล้ายกับIEnumerable<T>อินเทอร์เฟซ (วิธีการขยายสำหรับในสถานที่Sort, BinarySearch... จะเป็นประโยชน์)


36
@ShdNx พวกเขาไม่ได้เป็นเรื่องเล็กน้อยที่จะใช้ประสิทธิภาพที่ชาญฉลาด "ภายใน" AddRange/RemoveRange/InsertRangeสามารถทำงานได้โดยตรงในคอลเลกชัน "ภายใน" และเพิ่มประสิทธิภาพการCapacityจัดการและใช้วิธีการต่างๆเช่นArray.Copyย้ายไปรอบ ๆ บล็อกข้อมูล วิธีการขยายRemoveRangeอาจเป็นลำดับการขยายที่ช้ากว่าList.RemoveRange
xanatos

2
มันแย่เกินไปที่ไม่มี (และยังไม่มี) วิธีใด ๆ สำหรับอินเทอร์เฟซ (เช่นIFoo) การประกาศเพื่อระบุเนมสเปซ "ตัวช่วย" (เช่นMyAssembly) เช่นหากคลาสอ้างว่าใช้งานIFooแต่ไม่มีเมธอดint Bar(String)คอมไพเลอร์จะอัตโนมัติ สร้างวิธีการint IFoo.Bar(String p1) {return MyAssembly.ClassHelpers.IFoo.Bar(this, p1);} หากมีคุณลักษณะดังกล่าวอินเทอร์เฟซอาจมีวิธีการอื่น ๆAddRangeที่สามารถนำไปใช้ในแง่ของพฤติกรรมพื้นฐานได้ แต่การใช้งานบางอย่างสามารถปรับให้เหมาะสมได้
supercat

1
พวกเขาสามารถนำไปใช้เป็นวิธีการส่วนขยายได้โดยที่การติดตั้งอินเทอร์เฟซไม่จำเป็นต้องใช้ ทำไมพวกเขาไม่?
Tom Pažourek

15
สิ่งนี้ไม่สมเหตุสมผล อินเทอร์เฟซเป็นนามธรรมของการนำไปใช้งานเพื่อให้สามารถใช้งานคุณสมบัติพื้นฐานเดียวกันได้หลายอย่าง ไม่มีเหตุผลว่าทำไมจึงควรละเว้นคุณลักษณะจากอินเทอร์เฟซเนื่องจาก "การนำไปใช้งานยาก" หากไม่มีวิธีการเช่น "AddRange" บนอินเทอร์เฟซจะไม่มีการรับประกันว่าวัตถุที่อยู่เบื้องหลังจะรองรับสิ่งเหล่านี้และ ณ จุดนั้นคุณจะถูกบังคับให้ใช้ส่วนขยายที่ไม่เหมาะสมหรือเอาชนะวัตถุประสงค์ของการใช้อินเทอร์เฟซโดยตั้งสมมติฐานที่เป็นอันตราย ส่งไปยังคลาสการใช้งานเฉพาะ อินเทอร์เฟซ Dumbed-down ถูกใช้งานมากเกินไป
Triynko

3
ควรมีอินเทอร์เฟซ IRangeList ที่รองรับการดำเนินการจำนวนมากโดยนำไปใช้งานในบางคอลเลกชันเท่านั้นซึ่งภายในจะมีการใช้งานที่เหมาะสมที่สุด
เกินไป

10

สำหรับผู้ที่ต้องการมีวิธีการขยายสำหรับ "AddRange", "Sort", ... บน IList,

ด้านล่างนี้เป็นAddRangeวิธีการขยาย:

 public static void AddRange<T>(this IList<T> source, IEnumerable<T> newList)
 {
     if (source == null)
     {
        throw new ArgumentNullException(nameof(source));
     }

     if (newList == null)
     {
        throw new ArgumentNullException(nameof(newList));
     }

     if (source is List<T> concreteList)
     {
        concreteList.AddRange(newList);
        return;
     }

     foreach (var element in newList)
     {
        source.Add(element);
     }
}

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

วิธีการบางอย่างช้ากว่า List แต่ได้ผล

นี่คือ GitHub ที่น่าสนใจ:

ที่เก็บ IListExtension


คุณสวย
Elnoor

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