2009-06-22 35 views

Trả lời

19

Toán tử chuyển đổi không thể là chung chung. Từ phần đặc tả 10.10, đây là định dạng của một chuyển đổi-hành-declarator:

conversion-operator-declarator: 
    implicit operator type ( type identifier ) 
    explicit operator type ( type identifier )

Hãy so sánh điều này với, chẳng hạn, một phương pháp-header:

phương pháp-header : thuộc tính chọn phương pháp sửa đổi chọn phần opt trở lại kiểu viên tên tuổi kiểu tham số-list opt ( chính thức tham số-list opt) kiểu tham số trở ngại-khoản chọn số

(Xin lỗi về định dạng - không chắc chắn cách đặt cược ter.)

Lưu ý rằng định dạng toán tử không bao gồm danh sách tham số kiểu hoặc nhập ràng buộc tham số.

+2

Và ngay cả khi chúng tôi đã hỗ trợ chuyển đổi chung do người dùng xác định, thì chuyển đổi này vẫn là bất hợp pháp. Việc xác định chuyển đổi thay thế một chuyển đổi được tích hợp là bất hợp pháp. Điều này sẽ làm như vậy nếu T và U là cùng loại; bạn sẽ thay thế chuyển đổi nhận dạng. –

+1

Khi phôi được quyết định bởi trình biên dịch, nếu T và U là cùng loại, thì nó sẽ không sử dụng người dùng định nghĩa diễn viên, và được leagal. –

2

Mã của bạn nắm để dòng: return new Foo<U>((U)a.Item)

đâu bạn cố gắng gán một baseclass để một lớp kế thừa, điều không thể.

Giả sử T (lớp cơ sở) thuộc loại Stream và U là loại MemoryStream (lớp kế thừa), bạn không thể gán Stream cho biến loại MemoryStream.

+0

Chắc chắn bạn có thể, Nếu tham chiếu mặt nạ đối tượng dưới dạng Luồng, nhưng nó sẽ ảnh hưởng đến MemoryStream, thì bạn chắc chắn có thể truyền nó vào luồng bộ nhớ. Đây là một phương pháp hợp pháp, vấn đề là bạn không thể chỉ định các ràng buộc chung trên một toán tử quá tải ... – LaserJesus

+0

... Nếu bạn lấy mã tôi có và diễn tả nó như một phương thức chứ không phải là một toán tử quá tải nó sẽ biên dịch – LaserJesus

0

Dường như bạn muốn có một chuyển đổi contravariant, nhưng struct s không thay đổi, chuyển đổi không mua cho bạn gì cả, bạn có thể chỉ cần nói new Foo<U>((U)a.Item) như @Gidon đã chỉ ra.

Nếu bạn coi thay đổi Foo trở thành một lớp, sau đó chúng ta có thể làm cho một số khác biệt:

public interface IFoo<in T> { 
    T Item { 
     set; 
    } 
} 

public class Foo<T>:IFoo<T> { 
    public Foo(T item) { 
     this.Item=item; 
    } 

    public T Item { 
     get; set; 
    } 

    // public static explicit operator Foo<U>(U a) { 
    // return new Foo<U>((U)a.Item); 
    // } 
} 

và sử dụng nó như:

var foo = new Foo<object>(new object { }); 
IFoo<String> bar = foo; 
bar.Item="123"; 
var b = Object.ReferenceEquals(foo, bar); // true 

Bằng cách này, khác biệt trong giao diện chung là chỉ khả dụng từ .netfx 4.0.

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