简体   繁体   English

不能将类型 [concrete] 隐式转换为 [interface]

[英]Cannot implicitly convert type [concrete] to [interface]

I know I risk a thrashing but I feel like I'm going in circles on this.我知道我冒着被殴打的风险,但我觉得我在绕圈子。 In order to have models available to multiple projects, we have moved the models out to a separate project (a DLL) as a series of interfaces to implement.为了让模型可用于多个项目,我们将模型移出到一个单独的项目(DLL)中,作为要实现的一系列接口。 On of our interfaces has this line:我们的一个接口有这一行:

List<IImportOrderLineModel> Lines { get; set; }

Which links to this interface:哪个链接到这个界面:

 public interface IImportOrderLineModel
    {
        string OrderNumber { get; set; }
        int? LineNumber { get; set; }
        string ItemId { get; set; }
        string CustomerItemId { get; set; }
        double? Quantity { get; set; }
        decimal? Price { get; set; }
        int? QuantityBackOrdered { get; set; }
        string Comments { get; set; }
        string PickLocation { get; set; }
        string OrderFilled { get; set; }
        string HostUom { get; set; }
        string Type { get; set; }
    }

So in code, when I implement the interfaces and set the properties, I am able to set them without any problem.所以在代码中,当我实现接口并设置属性时,我可以毫无问题地设置它们。 I have created a concrete implementation of both interfaces and filled them accordingly.我已经创建了两个接口的具体实现并相应地填充了它们。 Now I am trying to do this:现在我正在尝试这样做:

 Parallel.ForEach(orders, order =>
        {
            order.Lines = items.FindAll(x => x.OrderNumber == order.OrderNumber).ToList();

        });

In order to combine all the items into the corresponding Lines property for the orders.为了将所有项目组合到订单的相应 Lines 属性中。 Now this code worked fine when the models were included in the code, but is now broken when we moved them out as interfaces and implement them in a concrete method.现在,当模型被包含在代码中时,这段代码可以正常工作,但是当我们将它们作为接口移出并在具体方法中实现它们时,现在就被破坏了。 The error is:错误是:

Cannot implicitly convert type 'System.Collection.Generic.List<ImportOrderLineModel>' to 'System.Collections.Generic.List<IImportOrderLineModel>'

I have read about co-variance and the apple is not a fruit answers that have been given elsewhere, but this is a new one to me.我读过关于协方差的文章,苹果不是其他地方给出的水果答案,但这对我来说是一个新答案。 I have tried to use the following on the interface:我尝试在界面上使用以下内容:

 public interface IImportOrderLineModel<out ImportOrderLineModel> where ImportOrderLineModel : class, IImportOrderModel

But doing so generates an error on the line in the other interface:但是这样做会在另一个界面中产生一个错误:

List<IImportOrderLineModel> Lines { get; set; }

Using generic type 'IImportsOrderLineModel' requires 1 type arguments使用泛型类型 'IImportsOrderLineModel' 需要 1 个类型参数

How can I get past this?我怎样才能克服这个?

Looks like this may work:看起来这可能有效:

order.Lines = items.FindAll(x => x.OrderNumber == order.OrderNumber)
                   .Cast<IImportOrderLineModel>()
                   .ToList();

The accepted answer appears to be correct, but there are better ways to solve this problem.接受的答案似乎是正确的,但有更好的方法来解决这个问题。 The preferred solution would be:首选的解决方案是:

IEnumerable<IImportOrderLineModel> lines = 
  items.Where(x => x.OrderNumber == order.OrderNumber);
order.Lines = lines.ToList();

This solution eliminates two issues with the solution in Renat's answer:此解决方案消除了 Renat 答案中的解决方案的两个问题:

  • You start with a list and end with a list, so you'll need to create at least one new list.您以列表开始并以列表结束,因此您至少需要创建一个新列表。 But FindAll creates another list, unnecessarily.但是FindAll不必要地创建了另一个列表。 That's extra work, extra collection pressure, and so on, in exchange for no benefit.那是额外的工作、额外的收款压力等等,换来的却是没有​​任何好处。
  • The Cast<IImportOrderLineModel> operation similarly creates a new enumerator, but it is unnecessary; Cast<IImportOrderLineModel>操作类似地创建了一个新的枚举器,但它是不必要的; you can always simply do a covariant reference conversion for free to IEnumerable<IImportOrderLineModel> .您总是可以简单地免费将协变引用转换IEnumerable<IImportOrderLineModel>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM