2013-03-09 33 views
8
public interface PipelineElement<in TIn, out TOut> 
{ 
    IEnumerable<TOut> Run(IEnumerable<TIn> input, Action<Error> errorReporter); 
} 

public interface Stage 
{ 
} 

public abstract class PipelineElementBase<TIn, TOut> : PipelineElement<object, object>, 
    PipelineElement<TIn, TOut> where TIn : Stage where TOut : Stage 
{ 
    IEnumerable<object> PipelineElement<object, object>.Run(IEnumerable<object> input, Action<Error> errorReporter) 
    { 
     return this.Run(input.Cast<TIn>(), errorReporter).Cast<object>(); 
    } 

    public abstract IEnumerable<TOut> Run(IEnumerable<TIn> input, Action<Error> errorReporter); 
} 

object không thực hiện Stage, do đó không phải TIn cũng không TOut bao giờ có thể là object, phải không? Vậy tại sao trình biên dịch lại nghĩ rằng PipelineElement<object, object>PipelineElement<TIn, TOut> có thể trở thành giống hệt nhau?Tại sao điều này dẫn đến CS0695?

EDIT: Vâng, nó là hoàn toàn có thể thực hiện cùng một giao diện chung nhiều lần:

public interface MyInterface<A> { } 
public class MyClass: MyInterface<string>, MyInterface<int> { } 
+0

tôi loại bỏ ý kiến ​​của tôi, tôi đã không có gì hữu ích. Đánh dấu là yêu thích, tôi cũng muốn biết câu trả lời :). 1 cho câu hỏi mặc dù! – bas

Trả lời

7

Từ Compiler Error CS0695

'loại chung' không thể thực hiện cả hai 'giao diện chung' và 'chung giao diện 'vì chúng có thể hợp nhất cho một số thông số loại thay thế.

Lỗi này xảy ra khi một lớp chung thực hiện nhiều hơn một tham số của cùng một giao diện chung và có một thay thế tham số kiểu làm cho hai giao diện giống hệt nhau. Để tránh lỗi này, chỉ thực hiện một trong các giao diện, hoặc thay đổi các thông số loại để tránh xung đột.

Bạn không thể triển khai cả giao diện PipelineElementBase<TIn, TOut>PipelineElement<object, object> vào lớp trừu tượng của mình.

Khi trang lỗi cho biết, bạn nên;

  • Thực hiện chỉ một trong các hoặc
  • Thay đổi các thông số loại để tránh xung đột.

Từ C# 5.0 Language Specification

13.4.2 Tính độc đáo của giao diện được cài

Các giao diện được thực hiện bởi một tuyên bố loại generic phải còn duy nhất cho tất cả các loại xây dựng tốt. Nếu không có quy tắc này, nó sẽ không thể xác định phương thức chính xác để gọi cho một số loại được xây dựng nhất định là .Ví dụ, giả sử một tuyên bố chung lớp được phép được viết như sau:

interface I<T> 
{ 
    void F(); 
} 
class X<U,V>: I<U>, I<V> 
{ 
    void I<U>.F() {...} 
    void I<V>.F() {...} 
} 

Were này cho phép, nó sẽ không thể để xác định mã để thực hiện trong trường hợp sau đây:

I<int> x = new X<int,int>(); 
x.F(); 

Để xác định danh sách giao diện của khai báo loại chung là hợp lệ, các bước sau đây được thực hiện:

  • Hãy L là danh sách các giao diện chỉ định trực tiếp trong một lớp học chung, cấu trúc, hoặc tuyên bố giao diện C.

  • Thêm vào L bất kỳ giao diện cơ bản của giao diện đã có trong L.

  • Hủy bỏ bất kỳ bản sao từ L.

  • Nếu bất kỳ loại xây dựng có thể được tạo ra từ C sẽ, sau khi tranh luận kiểu được thay ra L, khiến hai giao diện trong L là giống hệt nhau, khi đó khai báo C không hợp lệ. Các tờ khai Ràng buộc không được xem xét khi xác định tất cả các loại có thể là được xây dựng.

Trong tuyên bố lớp X trên, danh sách giao diện L gồm I<U>I<V>. Tuyên bố không hợp lệ vì bất kỳ loại nào được xây dựng với UV là cùng loại sẽ khiến hai giao diện này là là các loại giống hệt nhau.

Có thể cho các giao diện quy định tại mức thừa kế khác nhau để thống nhất:

interface I<T> 
{ 
    void F(); 
} 
class Base<U>: I<U> 
{ 
    void I<U>.F() {…} 
} 
class Derived<U,V>: Base<U>, I<V> // Ok 
{ 
    void I<V>.F() {…} 
} 

Mã này là hợp lệ mặc dù Derived<U,V> thực hiện cả hai I<U>I<V>. Mã

I<int> x = new Derived<int,int>(); 
x.F(); 

gọi phương pháp này trong Derived, vì Derived<int,int> hiệu quả tái cụ I<int> (§13.4.6).

[Nhấn mạnh bởi các biên tập viên SO.]

+0

Xung đột nào? Với những ràng buộc kiểu này, '' và '' không thể va chạm. –

+5

@ main-- "Khai báo hạn chế không được xem xét khi xác định tất cả các loại được xây dựng có thể." Đây là linchpin của vấn đề của bạn, nhưng câu trả lời này buries rằng câu quan trọng trong quá nhiều chi tiết IMHO. –

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