【问题标题】:How to assign List<Parent> to List<Child> which is parent extended with 2 additional properties?如何将 List<Parent> 分配给具有 2 个附加属性的父级扩展 List<Child>?
【发布时间】:2019-12-08 01:52:44
【问题描述】:

我正在制作 ASP.NET MVC 应用程序,并且我有 Order 类,但我想在其中添加 2 个附加属性以供查看。我发现我将只创建一个类ViewOrder,它派生自Order 并具有2 个附加属性,因此我可以将Order 对象分配给OrderView,然后设置这2 个属性并将此对象传递给查看。

这是正确的方法吗?当我在寻找关于铸造的答案时,人们给出了诸如“猫继承自哺乳动物。你不能将哺乳动物铸造成猫,因为它可能是一只狗”之类的例子。

列表:

var orderList = new List<Order>(_context.Orders)

就像它甚至无法编译:

List<OrderView> orderViewList = (List<OrderView>)orderList;

此编译但抛出“InvalidCastException”:

var orderViewList = orderList.Cast<OrderView>().ToList();

【问题讨论】:

  • 你不能从一个基本类型的对象转换为一个更派生的类型,这就是你最后得到一个 InvalidCastException 的原因。由于源列表中的对象是订单,而不是 OrderView,因此您不能将订单强制转换为 OrderView。
  • OrderView总是Order,但Order 并不总是OrderView。你可以做类似orderList.Select(order =&gt; new OrderView() { newprop = '', newprop1 = '', ///rest }).ToList()
  • 而且List&lt;BaseType&gt; 不是List&lt;DerivedType&gt; 的基本类型,泛型不能那样工作,这就是中间代码无法编译的原因。

标签: c# asp.net asp.net-mvc


【解决方案1】:

可能最简单的解决方案是执行显式映射操作:

List<Order> orderList = new List<Order>(_context.Orders);
List<OrderView> orderViewList = new List<OrderView>();  // Empty.

foreach (Order order in orderList)
{
    OrderView orderView = new OrderView;
    orderView.OrderNo = order.OrderNo;
    orderView.CustomerId = order.CustomerId;
    // ... etc
    orderViewList.Add(orderView);
}

【讨论】:

  • 是的,但我想避免这种情况
  • 你能分享你的代码@kkamil4sz,这样我们就可以提出最好的方法,因为根据我们目前所知道的,robbpriestkey 的答案就是方法。
  • 我的意思是,我想要一些比手动映射所有父类属性(如 List = List)更快的方法,但我想我别无选择。
  • 我不会太在意它。
【解决方案2】:

您不能将基类转换为派生类,没有内置方法。您可以编写一个可以进行转换的构造函数 OrderView(Order) 并使用 Linq 使其看起来干净。

// OrderView constructor
public OrderView(Order order)
{
    this.OrderNo = order.OrderNo;
}

// Linq to create new list
List<OrderView> orderView = orders.Select(o => new OrderView(o));

或者这样用,但不推荐

List<Order> orders = new List<OrderView>();

【讨论】:

  • 我仍然需要映射所有内容,但是是的,至少我只需要做一次
【解决方案3】:

我必须为之前的回答道歉。问题出在这里:

List&lt;OrderView&gt; orderViewList = (List&lt;OrderView&gt;)orderList; //&lt;== Casting

真正的事实是:OrderOrderview 的父级。因此,您无法创建父级并将其分配给子级。您只能创建一个子级并将其分配给父级。

所以,OrderViewOrder 的另一个版本。但是Order 不是OrderView 的一个版本。

这是一个完整的例子:

当一个孩子被分配给一个父母时,这个父母没有而孩子拥有的任何其他功能都会被忽略。但是,当父级分配给子级时,父级需要子级所需的功能。这会产生这个铸造问题。

我不确定您尝试做的事情从长远来看是否会为您服务,但可能有更好的方法来做这件事。请提供您的Order 课程,并确定您特别希望通过OrderView 实现的目标。因为按照我的理解,OrderView 应该是Order 中的一个方法,它提供了Order 的表示,您可以简单地将您提到的那些额外字段创建为私有字段,以便您可以使用它们来创建这个@987654333 @方法。

【讨论】:

  • 我得到“无法将 Generic.List 隐式转换为 Generic.List
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-13
  • 1970-01-01
  • 2019-07-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多