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

Rob*_*obs 4 .net c# linq generics collections

我想转换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
}
Run Code Online (Sandbox Code Playgroud)

有什么想法吗?

jas*_*son 25

用途Enumerable.Cast:

return query.Cast<ICompany>().ToList();
Run Code Online (Sandbox Code Playgroud)

一些评论:

List<Company> companies = new List<Company>();
Run Code Online (Sandbox Code Playgroud)

这会创建一个新列表.但你永远不会使用它,因为你有两行

companies = query.ToList();
Run Code Online (Sandbox Code Playgroud)

覆盖您创建的列表(以及您从未引用的中间行companies).如果您愿意,您可以一举声明并获得结果:

List<Company> companies = query.ToList();
Run Code Online (Sandbox Code Playgroud)

其次,如果您只是想返回结果列表,那么这一切都是不必要的.简洁(在某种程度上)是编程的一大优点."少即是多"就是这样的说法,因为代码越少意味着编写代码越少,测试代码越少,维护代码越少.通过编写更少的代码即可提高生产力 这是您的方法的简短版本:

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

甚至

public List<ICompany> FindAll() {
    return _scope.Extent<Company>().Cast<ICompany>().ToList();
}
Run Code Online (Sandbox Code Playgroud)

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

最后,你应该检查一下你是否真的需要返回一个List.您使用的列表中有哪些方法?如果你只是用它来枚举结果(foreach(var item in list))那么你应该返回一个IEnumerable<ICompany>:

public IEnumerable<ICompany> FindAll() {
    return _scope.Extent<Company>().Cast<ICompany>();
}
Run Code Online (Sandbox Code Playgroud)