ความแปรปรวนจะได้รับการสนับสนุนในวิธีที่ปลอดภัยเท่านั้น - ในความเป็นจริงโดยใช้ความสามารถที่ CLR มีอยู่แล้ว ดังนั้นตัวอย่างที่ผมให้ไว้ในหนังสือพยายามที่จะใช้ที่List<Banana>
เป็นList<Fruit>
(หรือสิ่งที่มันเป็น) ยังจะไม่ทำงาน - แต่สถานการณ์อื่น ๆ ไม่กี่จะ
ประการแรกจะรองรับเฉพาะอินเทอร์เฟซและผู้รับมอบสิทธิ์เท่านั้น
ประการที่สองต้องมีผู้สร้างอินเทอร์เฟซ / ผู้รับมอบสิทธิ์ในการตกแต่งพารามิเตอร์ประเภทเป็นin
(สำหรับความแตกต่าง) หรือout
(สำหรับความแปรปรวนร่วม) ตัวอย่างที่ชัดเจนที่สุดคือIEnumerable<T>
สิ่งที่ให้คุณ "ออก" จากค่านี้เท่านั้น แต่จะไม่ให้คุณเพิ่มค่าใหม่ IEnumerable<out T>
ที่จะกลายเป็น นั่นไม่ได้ทำร้ายความปลอดภัยของประเภทเลย แต่ให้คุณส่งคืนIEnumerable<string>
จากวิธีการที่ประกาศให้ส่งคืนIEnumerable<object>
ตัวอย่างเช่น
ความแตกต่างนั้นยากที่จะยกตัวอย่างที่เป็นรูปธรรมสำหรับการใช้อินเทอร์เฟซ แต่เป็นเรื่องง่ายสำหรับผู้ร่วมประชุม พิจารณาAction<T>
- นั่นแสดงถึงวิธีการที่ใช้T
พารามิเตอร์ จะเป็นการดีที่จะสามารถแปลงใช้ an Action<object>
เป็น an ได้อย่างราบรื่นAction<string>
- วิธีการใด ๆ ที่ใช้object
พารามิเตอร์จะดีเมื่อนำเสนอด้วย a string
แทน แน่นอน C # 2 มีความแปรปรวนร่วมและความแตกต่างของผู้ร่วมประชุมอยู่แล้วในระดับหนึ่ง แต่ผ่านการแปลงจริงจากประเภทผู้รับมอบสิทธิ์หนึ่งไปยังอีกประเภทหนึ่ง (การสร้างอินสแตนซ์ใหม่) - ดูตัวอย่าง P141-144 C # 4 จะทำให้สิ่งนี้กว้างขึ้นและ (ฉันเชื่อว่า) จะหลีกเลี่ยงการสร้างอินสแตนซ์ใหม่สำหรับการแปลง (จะเป็นการแปลงอ้างอิงแทน)
หวังว่าสิ่งนี้จะกระจ่างขึ้นสักหน่อย - โปรดแจ้งให้เราทราบหากไม่สมเหตุสมผล!