List <T>เป็นคลาสและใช้ทั้งICollection <T>และIEnumerable <T>อินเตอร์เฟส นอกจากนี้ ICollection <T> ยังขยายส่วนต่อประสาน IET ที่นับได้อีกด้วย พวกมันไม่สามารถใช้แทนกันได้อย่างน้อยก็ไม่ใช่จากมุมมองทั้งหมด
หากคุณมีรายการ <T> คุณจะรับประกันได้ว่าวัตถุนี้ใช้วิธีการและคุณสมบัติที่จำเป็นในการใช้งานโดย ICollection <T> และ IEnumerable <T> อินเตอร์เฟส คอมไพเลอร์รู้และคุณได้รับอนุญาตให้โยนพวกเขา "ลง" เพื่อ ICollection <T> หรือ IEnumerable <T> โดยปริยาย อย่างไรก็ตามหากคุณมี ICollection <T> คุณต้องตรวจสอบอย่างชัดเจนในรหัสของคุณก่อนว่ามันเป็นรายการ <T> หรืออย่างอื่นบางทีพจนานุกรม <T> (โดยที่ T คือKeyValuePair ) ก่อนที่จะส่งไปยังสิ่งที่คุณ ความต้องการ.
คุณรู้ว่า ICollection ขยายจำนวน IEnumerable ดังนั้นคุณสามารถแปลงมันเป็น IEnumerable แต่ถ้าคุณมีเพียง IEnumerable อีกครั้งคุณจะไม่รับประกันว่ามันเป็น List อาจเป็นได้ แต่อาจเป็นอย่างอื่น คุณควรคาดหวังข้อยกเว้นการส่งที่ไม่ถูกต้องหากคุณพยายามส่งรายการ <T> ไปยังพจนานุกรม <T>
ดังนั้นพวกเขาจะไม่ "ใช้แทนกันได้"
นอกจากนี้ยังมีอินเทอร์เฟซทั่วไปให้ตรวจสอบสิ่งที่คุณสามารถหาได้ในSystem.Collections.Generic namespace
แก้ไข: เกี่ยวกับความคิดเห็นของคุณไม่มีการลงโทษประสิทธิภาพหากคุณใช้รายการ <T> หรือหนึ่งในอินเตอร์เฟสที่ใช้ คุณยังจะต้องสร้างวัตถุใหม่ลองดูรหัสต่อไปนี้:
List<T> list = new List<T>();
ICollection<T> myColl = list;
IEnumerable<T> myEnum = list;
รายการ , myCollและMyEnumชี้ไปที่วัตถุเดียวกัน ไม่ว่าคุณจะประกาศเป็นรายการหรือ ICollection หรือ IEnumerable ฉันยังต้องการให้โปรแกรมสร้างรายการ ฉันน่าจะเขียนสิ่งนี้:
ICollection<T> myColl = new List<T>();
myColl , ที่รันไทม์ยังคงเป็นรายการ
อย่างไรก็ตามนี่คือจุดที่สำคัญที่สุด ... เพื่อลดการมีเพศสัมพันธ์และเพิ่มการบำรุงรักษาคุณควรประกาศตัวแปรและพารามิเตอร์วิธีการของคุณโดยใช้ตัวหารที่เป็นไปได้ต่ำสุดที่เป็นไปได้สำหรับคุณไม่ว่าจะเป็นอินเทอร์เฟซหรือคลาสนามธรรมหรือคอนกรีต
ลองจินตนาการว่าสิ่งเดียวที่เมธอด "PerformOperation" ต้องการคือการระบุองค์ประกอบทำงานและออกบางอย่างในกรณีที่คุณไม่ต้องการวิธีการนับร้อยที่มีอยู่ในรายการ <T> คุณต้องการเพียงสิ่งที่มีอยู่ใน IEnumerable <T > ดังนั้นควรใช้สิ่งต่อไปนี้:
public void PerformOperation(IEnumerable<T> myEnumeration) { ... }
โดยการทำเช่นนั้นคุณและนักพัฒนาอื่น ๆ รู้ว่าวัตถุใด ๆ ของคลาสที่ใช้อินเทอร์เฟซ IEnumerable <T> อาจถูกมอบให้กับวิธีนี้ อาจเป็นรายการพจนานุกรมหรือคลาสคอลเล็กชันที่กำหนดเองซึ่งผู้พัฒนารายอื่นได้เขียนไว้
หากในทางตรงกันข้ามคุณระบุว่าคุณต้องการรายการที่ชัดเจน <T> (และแม้ว่ามันจะไม่ค่อยเกิดขึ้นในชีวิตจริง แต่ก็อาจเกิดขึ้นได้) คุณและนักพัฒนาอื่น ๆ รู้ว่ามันต้องเป็นรายการหรือการสืบทอดคลาสอื่น จากรายการ