2010-05-11 17 views
6

Tôi có thể có một loại (để quên ngữ nghĩa của nó) mà có thể là biến thể cũng như contravariant?Tôi có thể có một loại cả hai, biến thể và contravariant, tức là hoàn toàn có thể thay đổi được với các loại phụ và siêu?

ví dụ:

public interface Foo<in out T> 
{ 
    void DoFooWith(T arg); 
} 

Tắt lên blog Eric Lippert cho thịt và khoai tây phương sai trong C# 4.0 như có rất ít khác bất cứ nơi nào mà bao gồm mặt đất đầy đủ về đề tài này.


Tôi đã thử nó dù sao đi nữa, nó không chỉ cho phép điều đó, mà còn cho tôi biết tôi đang thiếu điểm. Tôi cần hiểu liên kết giữa chỉ đọc, chỉ ghi và phương sai.

Tôi đoán tôi có một số đọc sách để thực hiện.

Tuy nhiên, bất kỳ câu trả lời ngắn, hiển linh nào cũng được chào đón.

Trả lời

7

Không, bạn không thể làm điều đó.

Giả sử đó là hợp pháp. Bạn thực hiện một số IFoo<Giraffe>. Vì IFoo là biến thể trong T, bạn có thể chuyển đổi nó qua chuyển đổi tham chiếu typesafe thành IFoo<object>. Vì nó là contravariant, bạn có thể chuyển đổi nó thành IFoo<Banana>. Những ngữ nghĩa có thể có cho IFoo<T> sao cho có thể chuyển đổi IFoo của Hươu cao cổ thành IFoo của Chuối thông qua chuyển đổi tham chiếu? Hươu cao cổ và Chuối không có điểm chung nào ngoài việc là loại tham chiếu. Bạn không thể có một phương thức trên IFoo<Banana> trả về Chuối, vì nó thực sự có thể là việc triển khai IFoo<Giraffe>; làm thế nào tác giả của việc thực hiện biết để đưa ra một quả chuối? Bạn không thể có một phương pháp trên IFoo<Banana> mà phải mất một chuối cho cùng một lý do; người triển khai IFoo<Giraffe> đang mong bạn đưa cho anh ta một con hươu cao cổ.

Dưới đây là một cách khác để nhìn vào nó:

  • "trong T" có nghĩa là (khoảng) "T chỉ xuất hiện ở những vị trí đầu vào".
  • "ra T" có nghĩa là (gần) "T chỉ xuất hiện ở vị trí đầu ra".

Do đó "trong T" có nghĩa là ... cái gì? Như chúng ta đã thấy, nó chỉ có thể có nghĩa là "T không xuất hiện ở tất cả trong bất kỳ phương pháp hay tài sản nào." Điểm của việc tạo một loại chung trong T mà bạn không bao giờ sử dụng T là gì?

+1

Thực ra, các loại chung chung không sử dụng các đối số kiểu chung của chúng có thể cực kỳ hữu ích. Vì vậy, được gọi là "loại ma" cho phép mã được viết theo cách như vậy mà các hoạt động không chính xác có thể được tĩnh không được phép. Ví dụ kinh điển có lẽ là kiểu 'File ', trong đó kiểu 'T' mã hóa xem tệp có cho phép đọc, viết hay cả hai mặc dù nội bộ của lớp không bao giờ tham chiếu' T'. – kvb

+0

Tất nhiên, bạn có thể dễ dàng vi phạm lợi ích an toàn của các loại phantom nếu loại được chú thích là cả hai biến và contravariant, vì sau đó bạn có thể chuyển đổi một 'File ' thành 'File ', như bạn lưu ý. – kvb

+2

@kvb: Làm thế nào mà bất kỳ khác nhau từ chỉ đơn giản là làm cho một lớp cơ sở File và các lớp học có nguồn gốc "WritableFile", "ReadableFile" và "ReadableAndWritableFile"? Tại sao chụp một cái gì đó trong hệ thống loại chung khi nó có thể chỉ đơn giản là bị bắt trong hệ thống kiểu thông thường? –

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