โซลูชันที่ทันสมัยกว่า
หากคุณไม่ต้องการให้คอลเลกชันภายในเปลี่ยนแปลงได้คุณสามารถใช้System.Collections.Immutable
แพ็กเกจเปลี่ยนประเภทฟิลด์ของคุณเป็นคอลเล็กชันที่ไม่เปลี่ยนรูปได้จากนั้นเปิดเผยสิ่งนั้นโดยตรงโดยสมมติว่าFoo
ตัวเองไม่เปลี่ยนรูปแน่นอน
อัปเดตคำตอบเพื่อตอบคำถามได้ตรงประเด็นมากขึ้น
มีเหตุผลใดหรือไม่ที่จะเปิดเผยคอลเลกชันภายในเป็น ReadOnlyCollection แทนที่จะเป็น IEnumerable หากรหัสการโทรวนซ้ำบนคอลเลกชันเท่านั้น
ขึ้นอยู่กับว่าคุณเชื่อถือรหัสการโทรมากแค่ไหน หากคุณสามารถควบคุมทุกสิ่งที่จะเรียกสมาชิกรายนี้ได้อย่างสมบูรณ์และคุณรับประกันได้ว่าจะไม่มีรหัสใดใช้:
ICollection<Foo> evil = (ICollection<Foo>) bar.Foos;
evil.Add(...);
แน่นอนว่าจะไม่เกิดอันตรายใด ๆ หากคุณส่งคืนคอลเลกชันโดยตรง โดยทั่วไปแล้วฉันพยายามที่จะหวาดระแวงมากกว่านั้นเล็กน้อย
ในทำนองเดียวกันอย่างที่คุณพูด: ถ้าคุณต้องการ เพียงอย่างเดียวIEnumerable<T>
ทำไมต้องผูกมัดตัวเองกับสิ่งที่แข็งแกร่งกว่า?
คำตอบเดิม
หากคุณใช้. NET 3.5 คุณสามารถหลีกเลี่ยงการทำสำเนาและหลีกเลี่ยงการแคสต์แบบธรรมดาได้โดยใช้การเรียกง่ายๆเพื่อข้าม:
public IEnumerable<Foo> Foos {
get { return foos.Skip(0); }
}
(มีตัวเลือกอื่น ๆ อีกมากมายสำหรับการตัดทอนเล็กน้อย - สิ่งที่ดีเกี่ยวกับSkip
Select / Where คือไม่มีผู้รับมอบสิทธิ์ที่จะดำเนินการอย่างไร้จุดหมายสำหรับการทำซ้ำแต่ละครั้ง)
หากคุณไม่ได้ใช้. NET 3.5 คุณสามารถเขียน Wrapper ง่ายๆเพื่อทำสิ่งเดียวกัน:
public static IEnumerable<T> Wrapper<T>(IEnumerable<T> source)
{
foreach (T element in source)
{
yield return element;
}
}
ReadOnlyCollection
กรณีที่คุณหวาดระแวง แต่ตอนนี้คุณไม่ได้ผูกติดอยู่กับการนำไปใช้งานใด