如何将List<Company>转换为List<ICompany>

4

我希望将 List<Company> 转换为 List<ICompany>

ICompany 是一个接口,Company 实现了该接口。

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
}

有什么想法吗?

4个回答

25

使用Enumerable.Cast

return query.Cast<ICompany>().ToList();
一些评论:
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<ICompany>

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

1
对于这个很好的解释(并根据最后一条评论进行调整...),点赞! - Reed Copsey
是的,谢谢你指出这一点,这使我比起最初更仔细地检查了他的代码。 - jason
很好的评论。也许是因为我被困在2.0时代,但是不需要一个“return”吗? - g .

3
return companies.Cast<ICompany>().ToList(); 

1
除了Enumerable.Cast的答案之外,如果你发现自己经常在Company和ICompany的集合之间转换,另一个建议可能是从Collection<T>派生自己的集合类,称为CompanyCollection,并让它实现IList<ICompany>。
如果你正在使用.NET 4.0(目前处于测试版),你可以利用泛型协变性,这样你就可以更隐式地完成这个操作。

+1 因为提到了协方差(并对这是唯一的答案感到惊讶) - Tamás Szelei

0
如果出于某些原因您不想使用Enumerable.Cast(尽管我建议除了其他评论之外也这样做),您可以始终执行以下操作:
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。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接