Giả sử tôi muốn có một lớp chung Box
có thể chứa nội dung nào đó bên trong, vì vậy, đó là Box<T>
. Box<T>
có một phương pháp Transform
mà trả về một Box<U>
:Các kiểu mẫu kỳ lạ định kỳ với các loại chung bổ sung
public Box<U> Transform<U>(Func<T, U> transform)
Cho đến nay điều này đã được khá đơn giản. Tuy nhiên, tôi thực sự cần một trừu tượng Box
, vì cách các giá trị được đóng hộp và chuyển đổi được thực hiện cụ thể. (Tôi không thể có một giao diện vì có các phương thức khác được triển khai thông qua thành phần của các phương thức trừu tượng, nhưng điều này không thay đổi bất cứ thứ gì).
Tất nhiên, tôi muốn tôi ghi đè các phương thức Transform
để trả lại một lớp con thích hợp của Box
, chứ không phải là Box
. Kể từ khi loại trở lại của phương pháp trọng là bất biến trong C#, tôi chuyển sang curiously recurring template pattern (xem IComparable<T>
):
public abstract class Box<B, T> where B : Box<B, T>
Bây giờ mỗi lớp tôi kế thừa từ Box<B, T>
nên tham khảo bản thân hoặc toàn phá vỡ địa ngục mất:
public class FooBox<T> : Box<FooBox, T>
Tuy nhiên, điều này hoàn toàn phá hủy các Transform
phương pháp:
public abstract Box<B, U> Transform<U>(Func<T, U> transform);
thất bại trong việc biên dịch với The type 'B' cannot be used as type parameter 'B' in the generic type or method 'Test.Box<B,T>'. There is no implicit reference conversion from 'B' to 'Test.Box<B,U>'. (CS0311)
. Điều đó có ý nghĩa, vì kiểu trả về bây giờ là Box<B, U>
và B là Box<B, T>
, không phải là Box<B, U>
.
Việc sửa chữa đơn giản sẽ không làm việc:
public abstract Box<B, U> Transform<U>(Func<T, U> transform) where B : Box<B, U>;
thất bại trong việc biên dịch với 'Test.Box<B,T>.Transform<U>()' does not define type parameter 'B' (CS0699)
.
Có cách nào để giải quyết vấn đề này hay tôi thực sự vẽ mình vào một góc?
có thể bạn chỉ cần làm cho nó một 'Hộp 'và chuyển thông tin thực hiện cụ thể trong thông qua các phương pháp nhà máy? –
@MillieSmith loại bỏ CRTP sẽ hoạt động, tất nhiên, nhưng điều đó sẽ dẫn đến việc không thể kiểm soát các phương thức đó như 'Hộp Kết hợp (Hộp khác, Func merge)' thực sự chấp nhận 'Hộp' tương thích. –
Alexey