【问题标题】:C# Declaring Type Definition Cannot create an instance of the abstract class or interfaceC# 声明类型定义无法创建抽象类或接口的实例
【发布时间】:2018-10-14 13:46:29
【问题描述】:

我创建了一个类 Cartline。然后我创建了一个名为 ShoppingCart 的集合。 当我尝试声明 ShoppingCart 时,我收到错误消息。有谁知道解决这个问题?

public class CartLine
{
    public int CartLineId { get; set; }
    public Product Product { get; set; }
    public int Quantity { get; set; }
}


using ShoppingCart = System.Collections.Generic.IEnumerable<ElectronicsStore.Models.CartLine>;

ShoppingCart shoppingcart = new ShoppingCart();

Cannot create an instance of the abstract class or interface 'IEnumerable<CartLine>'    ElectronicsStore

【问题讨论】:

  • ShoppingCart 设置为 IEnumerable,这是一个接口 - 您无法实例化接口。将其更改为 List
  • 谢谢,为什么不 ShoppingCart shoppingcart = new IEnumerable(); , 而不是 List?
  • @StevenMayer 解释了原因。 IEnumerable&lt;T&gt; 是一个接口。您不能创建接口实例,只能创建具体类。
  • 我真正想做的是为 (List of Cartlines) = ShoppingCart 创建一个同义词,我如何声明 ShoppingCart,除了一次之外不提及 Cartlines?我想在整个程序中多次声明购物车
  • 另外,希望能够访问购物车中的购物车成员,包括产品、数量,并像这样运行 foreach @foreach (var line in shoppingcart.cartline ) { @Html.DisplayFor(modelItem => line.Product) }

标签: c# asp.net-core


【解决方案1】:

错误是不言自明的。两个选项 - 您可以使用具体类型(例如 List&lt;CartLine&gt;)创建别名,但我建议您定义一个继承自 List&lt;CartLine&gt; 的类(或最适合您需要的任何集合):

public class ShoppingCart : List<CartLine>
{
    // implement constructors you want available
    public ShoppingCart(){}

    public ShoppingCart( IEnumerable<CartLine> collection ) : base( collection ) {}

    public ShoppingCart( int capacity ) : base( capacity ) {}

    // the benefit here is you can add useful properties
    // if CartLine had a price you could add a Total property, for example:
    public decimal Total => this.Sum( cl => cl.Quantity * cl.Price );
}

那么你可以按要求使用:

var cart = new ShoppingCart();
cart.Add( new CartLine() { ... } );
var cartTotal = cart.Total;
... etc ...

集合初始化器也可以工作:

var cart = new ShoppingCart() { new CartLine() { ... }, ... }

或使用现有的IEnumerable&lt;CartLine&gt; 进行初始化,例如使用实体框架的IQueryable&lt;CartLine&gt;

var cart = new ShoppingCart( dbContext.CartLines.Where( ... ) );

【讨论】:

  • 我注意到这个解决方案只需要@foreach(模型中的变量项),我将不得不阅读基础(集合)
  • 是的,ShoppingCart 在这个实现中是一个IEnumerable&lt;CartLine&gt;。采用Enumerable&lt;CartLine&gt; 参数的构造函数允许使用现有的IEnumerable&lt;CartLine&gt; 来初始化集合,因此,例如,如果您使用EF 加载CartLine 实体,您可以简单地调用new ShoppingCart( dbContext.CartLines.Where( ... ) );
【解决方案2】:

最简单的解决方案是创建一个名为 ShoppingCart 的新类,它的属性是 CartLine 实体列表:

public class CartLine
{
    public int CartLineId { get; set; }
    public Product Product { get; set; }
    public int Quantity { get; set; }
}

public class ShoppingCart
{
    public IList<CartLine> CartLines {get;set;}
}


ShoppingCart shoppingcart = new ShoppingCart();

【讨论】:

  • 如果您使用此解决方案,请理解您需要将 IList(一个接口)实例化为一个具体的类,例如 List。这看起来像 IList cartLines = new List();那么你就可以 CartLines.Add(cartline)
  • 当我这样做时,我必须进行双重 foreach,请参阅此处,我试图避免双重 foreach stackoverflow.com/questions/52798897/…
  • @StevenMayer 也许最好在 ShoppingCart 构造函数中实例化它
  • @AminMozhgani 同意,如果您要通过购物车添加产品(这听起来很正确)。 TVLamp,在我看来,该视图的模型应该是 ShoppingCart,而不是 IEnumerable。然后你只需要通过 CartLines 进行遍历。如果一个用户有可能拥有多个购物车,那么就不能帮助双 foreach。
  • @TVLamp 为什么您的视图中有一个 ShoppingCarts 列表?这是什么意思?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-08-17
  • 1970-01-01
  • 2017-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多