考虑:
class Order
{
public List<OrderItem> OrderItems {get;set;}
}
class SalesOrder : Order
{
public List<SalesOrderItem> OrderItems {get;set;}
}
class OrderItem {}
class SalesOrderItem : OrderItem {}当试图施展
SalesOrder salesorder = new SalesOrder();
salesorder.OrderItems = List<SalesOrderItem>();
salesorder.OrderItems.Add(new SalesOrderItem());
Order order = salesorder;order.Orderitems为空。有什么方法可以让这个转换使用派生属性吗?
我已经尝试过与接口进行协变,但之后不能使用List,而且使用IEnumerable将不允许公共设置器。对如何做到这一点有什么想法吗?
发布于 2015-03-18 17:46:38
代码中有几个错误。看起来您混淆了一些面向对象的概念,以及它们在C#中的实现方式。
在您的代码中,您正在尝试从SalesOrder派生Order。这是最重要的错误:它违反了Liskov代换原理。特别是,它意味着派生类不能为其成员的签名添加额外的约束。请注意,您的SalesOrder类确实添加了这样的约束:订单项必须是SalesOrderItem类型,而Order类则接受从OrderItem派生的所有订单项。
相反,您需要的是专门化:SalesOrder类比Order类更严格:它只能包含SalesOrderItems。专业化是通过使用泛型来实现的。因此,您可以按照以下方式定义您的类:
public class Order<T> where T: OrderItem
{
public List<T> OrderItems { get; set; }
}
public class OrderItem
{
}
public class SalesOrder : Order<SalesOrderItem>
{
}
public class SalesOrderItem : OrderItem
{
}Update:为了说明为什么不可能将SalesOrder转换为Order<OrderItem>,请考虑以下静态方法:
public static void AddOrderItem(Order<OrderItem> order)
{
var item = new OrderItem();
order.OrderItems.Add(order);
}如果SalesOrder是从Order<OrderItem>派生的,则可以编写以下内容:
var order = new SalesOrder();
AddOrderItem(order);但是,这将导致类型错误,因为SalesOrder不能包含普通的OrderItem。现在,如果将SalesOrder转换为Order的唯一原因是读取命令项,则可以引入一个接口:
public interface IOrder
{
IEnumerable<OrderItem> GetItems();
}
public class Order<T> : IOrder where T: OrderItem
{
public List<T> OrderItems { get; set; }
public IEnumerable<OrderItem> GetItems()
{
return this.OrderItems;
}
}现在,您可以将SalesOrder对象转换为IOrder并读取订单项。
发布于 2015-03-18 17:42:56
这就是所谓的"影影“。
您的salesOrder有两个OrderItems属性-一个是只对SalesOrder可见的,另一个是只能对Orders可见的。子类中的OrderItems属性隐藏在父类中。您正在向一个项目中添加一个项,然后观察另一个项。
我认为您需要重新考虑您的设计,但是可以通过从子类中删除属性来解决这个问题:
class Order
{
public Order()
{
OrderItems = new List<OrderItem>();
}
public List<OrderItem> OrderItems {get;set;}
}
class SalesOrder : Order { }
class OrderItem {}
class SalesOrderItem : OrderItem {}另一个选项是使Order成为一个泛型类:
class Order<T> where T: OrderItem
{
public Order()
{
OrderItems = new List<T>();
}
public List<T> OrderItems {get;set;}
}
class SalesOrder : Order<SalesOrderItem> { }
class OrderItem {}
class SalesOrderItem : OrderItem {}SalesOrder salesorder = new SalesOrder();
salesorder.OrderItems.Add(new SalesOrderItem());
Order<SalesOrderItem> order = salesorder;第二种方法的好处是它允许OrderItems存储特定类型的订单项,而不是最普通的类型。
https://stackoverflow.com/questions/29128590
复制相似问题