Dưới đây là một giải pháp cho việc thay đổi giao diện:
interface IOrder<TOrder, TOrderItem>
where TOrderItem : IOrderItem<TOrder>
{
IList<TOrderItem> Items { get; set; }
}
interface IOrderItem<TOrder>
{
TOrder Parent { get; set; }
}
Thực hiện thay đổi để StoreOrder
và StoreOrderItem
để hỗ trợ thay đổi giao diện VÀ thêm một vài thuộc tính vào mỗi thử nghiệm sau:
class StoreOrder: IOrder<StoreOrder, StoreOrderItem>
{
public DateTime Date { get; set; }
public IList<StoreOrderItem> Items { get; set; }
}
class StoreOrderItem : IOrderItem<StoreOrder>
{
public string ItemName { get; set; }
public decimal ItemPrice { get; set; }
public StoreOrder Parent { get; set; }
}
... và bây giờ tạo StoreOrder
và StoreOrderItem
trường hợp, và đưa chúng thông qua các bước của họ:
void Main()
{
var so = new StoreOrder { Date = DateTime.Now };
var item = new StoreOrderItem {
Parent = so,
ItemName = "Hand soap",
ItemPrice = 2.50m };
so.Items = new [] { item };
Console.WriteLine(item.Parent.Date);
Console.WriteLine(so.Items.First().ItemName);
}
... khi chạy, in:
3/16/2012 10:43:55 AM
Hand soap
lựa chọn khác là để loại bỏ phần trên và lấy this solution và thay đổi nó bằng cách thêm thuộc tính Gốc với loại mong muốn và sử dụng triển khai giao diện rõ ràng để tránh truyền tại các trang gọi, làm cho một cái gì đó StoreOrderItem
thực hiện như thế này:
class StoreOrderItem : IOrderItem
{
public string ItemName { get; set; }
public decimal ItemPrice { get; set; }
public StoreOrder Parent { get; set; } // note: original implementation
IOrder<IOrderItem> IOrderItem.Parent { // explicit interface implementation
get { return (IOrder<IOrderItem>)this.Parent; }
set { this.Parent = (StoreOrder)value; }
}
}
ưa thích của tôi ở trên là đề xuất đầu tiên ở trên với các thông số hai tổng quát để IOrder
và không bị giới hạn generic-tham số trên IOrderItem
. Một phiên bản trước đó mà tôi đã đăng và hiện đã chỉnh sửa có cả hai giao diện, mỗi giao diện đều có hai loại chung giống nhau với cùng một ràng buộc.Tôi cảm thấy như thế này đã được một chút overboard vì vậy tôi pared nó trở lại thực hiện ở trên. Mặc dù thiếu hoàn toàn các ràng buộc đối với thông số loại TOrder
thành IOrderItem
- các nỗ lực nhằm giả mạo các loại khác tại vị trí của nó (ví dụ: object
) dẫn đến lỗi biên dịch. Sử dụng TOrder
thay vì chỉ gọi số T
cung cấp gợi ý về loại được mong đợi khi không có ràng buộc loại. Đó sẽ là bản chỉnh sửa cuối cùng của tôi - tôi cảm thấy nó là ngắn gọn nhất trong nỗ lực của tôi; nếu bạn tò mò, tôi có thể cung cấp việc triển khai thực hiện trước đó có các kiểu đôi-generic-constrained trên các giao diện, nhưng đây là ít nhất là giải pháp ưa thích của tôi. chúc mừng!
[Điều này có thể thú vị đối với bạn] (http://msdn.microsoft.com/en-us/library/dd469487.aspx) – abatishchev