Tôi sẽ cố gắng làm rõ câu trả lời của Anthony Pegram.
Kiểu chung là covariant trên một số đối số kiểu khi nó trả về các giá trị của kiểu đã nói (ví dụ Func<out TResult>
trả về các thể hiện của TResult
, IEnumerable<out T>
trả về các thể hiện của T
). Đó là, nếu một cái gì đó trả về các thể hiện của TDerived
, bạn cũng có thể làm việc với các thể hiện như thể chúng là của TBase
.
Loại chung là chống chỉ định đối với một số đối số loại khi nó chấp nhận các giá trị của loại đã nói (ví dụ: Action<in TArgument>
chấp nhận các thể hiện của TArgument
). Đó là, nếu một cái gì đó cần phiên bản của TBase
, bạn cũng có thể vượt qua trong trường hợp TDerived
.
Có vẻ khá hợp lý khi các loại chung chung chấp nhận và trả về các thể hiện của một số loại (trừ khi nó được xác định hai lần trong chữ ký loại chung, ví dụ CoolList<TIn, TOut>
) không phải là biến đổi cũng như chống đối với đối số loại tương ứng. Ví dụ, List
được định nghĩa trong .NET 4 là List<T>
, không List<in T>
hoặc List<out T>
.
Một số lý do tương thích có thể đã khiến Microsoft bỏ qua đối số đó và tạo ra các mảng đồng biến trên đối số loại giá trị của chúng. Có thể họ đã tiến hành phân tích và thấy rằng hầu hết mọi người chỉ sử dụng các mảng như thể họ chỉ đọc (nghĩa là họ chỉ sử dụng các công cụ khởi tạo mảng để ghi một số dữ liệu vào một mảng), và như vậy, những ưu điểm vượt trội hơn những nhược điểm do thời gian chạy có thể gây ra lỗi khi ai đó sẽ cố gắng sử dụng hiệp phương sai khi viết vào mảng. Do đó nó được cho phép nhưng không được khuyến khích.
Đối với câu hỏi ban đầu của bạn, hãy list.ToArray()
tạo một câu hỏi mới LinkLabel[]
với các giá trị được sao chép từ danh sách ban đầu và để loại bỏ cảnh báo (hợp lý), bạn sẽ cần chuyển Control[]
đến AddRange
. list.ToArray<Control>()
sẽ thực hiện công việc: ToArray<TSource>
chấp nhận IEnumerable<TSource>
làm đối số và trả về TSource[]
; List<LinkLabel>
thực hiện chỉ đọc IEnumerable<out LinkLabel>
, nhờ IEnumerable
hiệp phương sai, có thể được truyền cho phương thức chấp nhận IEnumerable<Control>
làm đối số của nó.
LinkLabel
(loại chuyên biệt) đếnControl
(loại cơ sở).