2010-03-29 25 views
18

lý do thực sự cho giới hạn đó là gì? Nó chỉ là công việc phải được thực hiện? Là khái niệm khó? Nó là bất khả thi?Tại sao C# (4.0) không cho phép đồng và contravariance trong các loại lớp chung?

Chắc chắn, người ta không thể sử dụng các tham số kiểu trong các trường, vì chúng là đọc-ghi allways. Nhưng đó không thể là câu trả lời, phải không?

Lý do cho câu hỏi này là tôi đang viết một bài viết về hỗ trợ phương sai trong C# 4, và tôi cảm thấy rằng tôi nên giải thích tại sao nó bị hạn chế đối với các đại biểu và giao diện. Chỉ để đảo ngược hậu quả của bằng chứng.

Cập nhật: Eric đã hỏi về một ví dụ.

gì về điều này (không biết nếu điều đó có ý nghĩa, tuy nhiên :-))

public class Lookup<out T> where T : Animal { 
    public T Find(string name) { 
    Animal a = _cache.FindAnimalByName(name); 
    return a as T; 
    } 
} 

var findReptiles = new Lookup<Reptile>(); 
Lookup<Animal> findAnimals = findReptiles; 

Lý do cho việc đó trong một lớp có thể là bộ nhớ cache mà được tổ chức trong lớp chính nó. Và xin vui lòng không đặt tên cho loại vật nuôi khác nhau của bạn giống nhau!

BTW, đây mang lại cho tôi để optional type parameters in C# 5.0 :-)

Cập nhật 2: Tôi không tuyên bố CLR và C# nên cho phép điều này. Chỉ cần cố gắng hiểu những gì đã dẫn đến điều đó nó không.

+1

Chắc chắn, đó là một ví dụ hợp lý nhưng bạn chưa thể hiện bất kỳ điều gì cũng không thể thực hiện được với giao diện. Chỉ cần tạo giao diện ILookup và có Tra cứu thực hiện nó. Lợi ích bổ sung hấp dẫn nào so với phương sai giao diện trong trường hợp của bạn cho phương sai lớp thêm? –

+1

Không, thực sự. Bên cạnh đó nó là ít mã. Hãy để tôi đảo ngược hậu quả của bằng chứng. Làm thế nào chúng ta có thể giải thích tại sao nó không được hỗ trợ. Tôi không yêu cầu thực hiện nó, thực sự. "Nó luôn luôn là như vậy" không tính! :-) –

+0

Chúng tôi không phải cung cấp một biện minh cho * không * triển khai tính năng. Không triển khai tính năng là * miễn phí *. Thay vào đó, chúng tôi phải cung cấp một biện minh cho việc thực hiện một tính năng - tính năng có thể tốn hàng triệu đô la cho Microsoft và áp đặt gánh nặng lớn hơn cho khách hàng của chúng tôi, những người phải dành thời gian và tiền bạc để tìm hiểu về tính năng này. –

Trả lời

18

Trước hết, như Tomas nói, nó không được hỗ trợ trong CLR.

Thứ hai, cách thức hoạt động? Giả sử bạn có

class C<out T> 
{ ... how are you planning on using T in here? ... } 

T chỉ có thể được sử dụng ở vị trí đầu ra. Như bạn lưu ý, lớp không thể có bất kỳ trường nào kiểu T vì trường có thể được ghi vào. Lớp không thể có bất kỳ phương thức nào có T, vì các phương thức này được ghi logic. Giả sử bạn có tính năng này - bạn sẽ tận dụng lợi thế của nó như thế nào?

Điều này sẽ hữu ích cho các lớp không thay đổi nếu chúng tôi có thể, nói, làm cho nó hợp pháp để có một trường chỉ đọc loại T; theo cách đó, chúng tôi đã cắt giảm một cách ồ ạt khả năng nó được viết không đúng cách. Nhưng nó khá khó khăn để đến với các kịch bản khác cho phép phương sai một cách an toàn.

Nếu bạn có kịch bản như vậy, tôi rất muốn xem nó. Đó sẽ là điểm hướng tới một ngày nào đó nhận được điều này được thực hiện trong CLR.

UPDATE: Xem

Why isn't there generic variance for classes in C# 4.0?

để biết thêm về câu hỏi này.

+1

Câu hỏi hay :) Tôi nhớ một cuộc thảo luận giữa Anders và một số trình biên dịch Java (xin lỗi) tại Lang.NET năm ngoái, nơi anh chàng Java đã yêu cầu tính năng này. Anh ta dường như không hiểu tại sao anh ta lại hỏi. Nhưng tôi không thể nhớ. Tôi nghĩ về các lớp học không có tiểu bang.Tôi sẽ cố gắng làm một cái gì đó trong câu hỏi. –

+1

Điều này chắc chắn sẽ là một tính năng tuyệt vời cho các kiểu dữ liệu bất biến như 'Tuple ', nhưng tôi đồng ý rằng điều này không đủ thuyết phục để thay đổi CLR :-). –

+3

Một trường hợp sử dụng khác là các kiểu phantom trong đó T chỉ được sử dụng cho an toàn kiểu và không được thực hiện trong lớp. – porges

8

Theo như tôi biết, tính năng này không được CLR hỗ trợ, vì vậy việc thêm tính năng này cũng sẽ yêu cầu công việc đáng kể ở phía CLR. Tôi tin rằng đồng và contra-phương sai cho các giao diện và đại biểu đã thực sự được hỗ trợ trên CLR trước phiên bản 4.0, vì vậy đây là một phần mở rộng tương đối đơn giản để thực hiện.

(Hỗ trợ tính năng này cho các lớp học sẽ chắc chắn có ích, mặc dù!)

+0

Bạn nói đúng. Phương sai trong các tham số kiểu generic của các giao diện và các đại biểu đi kèm với CLR 2.0 - không có trong C# –

1

Nếu được phép, các lớp hoặc cấu trúc hữu ích loại 100% (không có kiểu nội bộ) có thể được xác định là biến thể liên quan đến loại T, nếu người xây dựng chấp nhận một hoặc nhiều nhà cung cấp T hoặc T. Các lớp hoặc cấu trúc hữu ích, 100% an toàn có thể được định nghĩa là có thể so sánh với T nếu các nhà thầu của họ chấp nhận một hoặc nhiều người tiêu dùng T. Tôi không chắc có nhiều lợi thế của một lớp trên giao diện, ngoài khả năng sử dụng "mới" thay vì sử dụng phương thức nhà máy tĩnh (rất có thể từ một lớp có tên tương tự như giao diện), nhưng tôi có thể chắc chắn thấy các trường hợp sử dụng để có cấu trúc bất biến hỗ trợ hiệp phương sai.

Các vấn đề liên quan