ฉันจะพยายามชี้แจงคำตอบของแอนโทนี่เพกราม
ประเภททั่วไปเป็น covariant อาร์กิวเมนต์ชนิดบางอย่างเมื่อมันส่งกลับค่าจากประเภทกล่าว (เช่นFunc<out TResult>
กรณีของผลตอบแทนTResult
, IEnumerable<out T>
กรณีผลตอบแทนT
) นั่นคือถ้ามีบางสิ่งที่ส่งคืนอินสแตนซ์ของTDerived
คุณสามารถทำงานกับอินสแตนซ์นั้นได้เช่นTBase
กัน
ประเภทสามัญมีความขัดแย้งในบางประเภทอาร์กิวเมนต์เมื่อมันยอมรับค่าของประเภทดังกล่าว (เช่นAction<in TArgument>
ยอมรับกรณีของTArgument
) นั่นคือถ้าสิ่งที่ต้องการกรณีของคุณสามารถเป็นอย่างดีผ่านในกรณีของTBase
TDerived
ดูเหมือนว่ามีเหตุผลที่ประเภททั่วไปซึ่งทั้งสองยอมรับและส่งคืนอินสแตนซ์ของบางประเภท (ยกเว้นว่ามีการกำหนดสองครั้งในลายเซ็นประเภททั่วไปเช่นCoolList<TIn, TOut>
) ไม่ใช่ covariant หรือ contravariant บนอาร์กิวเมนต์ประเภทที่สอดคล้องกัน ยกตัวอย่างเช่นList
ที่กำหนดไว้ใน .NET 4 List<T>
ไม่ได้หรือList<in T>
List<out T>
เหตุผลความเข้ากันได้บางอย่างอาจทำให้ Microsoft เพิกเฉยต่ออาร์กิวเมนต์นั้นและสร้างอาร์เรย์ covariant บนอาร์กิวเมนต์ชนิดค่าของพวกเขา บางทีพวกเขาทำการวิเคราะห์และพบว่าคนส่วนใหญ่จะใช้อาร์เรย์ราวกับว่าพวกเขาอ่านได้อย่างเดียว (นั่นคือพวกเขาใช้เพียงตัวเริ่มต้นของอาเรย์ในการเขียนข้อมูลลงในอาเรย์) และดังนั้นข้อดีของข้อผิดพลาด ข้อผิดพลาดเมื่อมีคนพยายามใช้ความแปรปรวนร่วมเมื่อเขียนลงในอาร์เรย์ ดังนั้นจึงอนุญาต แต่ไม่ได้รับการสนับสนุน
สำหรับคำถามเดิมของคุณlist.ToArray()
สร้างใหม่LinkLabel[]
ที่มีค่าคัดลอกมาจากรายการเดิมและการกำจัดของการเตือน (ที่เหมาะสม) คุณจะต้องผ่านไปControl[]
จะทำงาน: ยอมรับว่าเป็นข้อโต้แย้งและผลตอบแทน; ใช้แบบอ่านอย่างเดียวซึ่งต้องขอบคุณความแปรปรวนร่วมซึ่งสามารถส่งผ่านไปยังวิธีการที่ยอมรับว่าเป็นอาร์กิวเมนต์AddRange
list.ToArray<Control>()
ToArray<TSource>
IEnumerable<TSource>
TSource[]
List<LinkLabel>
IEnumerable<out LinkLabel>
IEnumerable
IEnumerable<Control>
LinkLabel
(ประเภทเฉพาะ) เป็นControl
(ประเภทฐาน)