【问题标题】:How to convert List<Company> to List<ICompany>如何将 List<Company> 转换为 List<ICompany>
【发布时间】:2011-01-01 11:30:11
【问题描述】:

我想将List&lt;Company&gt; 转换为List&lt;ICompany&gt;

ICompanyCompany 实现的接口。

public List<ICompany> FindAll()
{
    List<Company> companies = new List<Company>();

    var query = from c in _scope.Extent<Company>()
                select c;

    companies = query.ToList();

    return companies.ToList<ICompany>(); // doesn't work
    //and
    return companies.ToList(); // doesn't work
}

有什么想法吗?

【问题讨论】:

    标签: c# .net linq generics collections


    【解决方案1】:

    使用Enumerable.Cast:

    return query.Cast<ICompany>().ToList();
    

    几个cmets:

    List<Company> companies = new List<Company>();
    

    这将创建一个新列表。但是你永远不会使用它,因为两行之后你就有了

    companies = query.ToList();
    

    覆盖您创建的列表(并且在中间行中您永远不会引用companies)。如果您愿意,您可以一举申报并获得结果:

    List<Company> companies = query.ToList();
    

    其次,如果您只是想返回结果列表,那么所有这些都是不必要的。简洁(在一定程度上)是编程的一大优势。 “少即是多”的说法是,更少的代码意味着更少的代码编写,更少的测试代码和更少的维护代码。通过编写更少的代码即时提高生产力!这是您方法的简短版本:

    public List<ICompany> FindAll() {
        var query = from c in _scope.Extent<Company>()
                    select c;
        return query.Cast<ICompany>().ToList();
    }
    

    甚至

    public List<ICompany> FindAll() {
        return _scope.Extent<Company>().Cast<ICompany>().ToList();
    }
    

    第三,您至少应该考虑返回IList 而不是List。最好编写接口而不是具体类型。这将您的代码与实现细节分离,使代码更易于更改和测试。

    最后,您应该检查是否真的需要返回List。您正在使用列表中的哪些方法?如果你只是用它来枚举结果(foreach(var item in list)),那么你应该返回一个IEnumerable&lt;ICompany&gt;

    public IEnumerable<ICompany> FindAll() {
        return _scope.Extent<Company>().Cast<ICompany>();
    }
    

    【讨论】:

    • +1 以获得很好的解释(并根据最后的评论进行调整......)
    • 是的,感谢您指出这一点,这使我对他的代码进行了比最初更仔细的检查。
    • 很棒的评论。也许是因为我被困在2.0的土地上,但不需要“返回”吗?
    【解决方案2】:

    除了 Enumerable.Cast 答案之外,如果您发现自己经常在 Company 和 ICompany 的集合之间穿梭,另一个建议可能是从名为 CompanyCollection 的 Collection 派生您自己的集合类,并让它实现 IList.

    如果您使用的是 .NET 4.0(目前处于测试阶段),您可以利用 generic covariance,它允许您更隐式地执行此操作。

    【讨论】:

    • +1 用于提及协方差(并惊讶于这是唯一的答案)
    【解决方案3】:

    如果由于某种原因您不想使用 Enumerable.Cast(尽管我建议您与其他 cmets 一起使用),您可以随时这样做:

    companies = query.ToList();
    List<ICompany> ret = new List<ICompany>();
    foreach (Company c in companies) 
    {
       ret.Add(c as ICompany);
    }
    

    这与 Skeolan 的解决方案几乎相同,但如果 (ICompany)c 失败,它会抛出。在我的代码中,c as ICompany 将在转换失败时返回 null。

    【讨论】:

      【解决方案4】:
      return companies.Cast<ICompany>().ToList(); 
      

      【讨论】:

        猜你喜欢
        • 2020-11-27
        • 2020-01-11
        • 2023-01-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-12-27
        • 2013-07-22
        • 1970-01-01
        相关资源
        最近更新 更多