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