使用linq,我可以搜索列表,访问属性并返回特定实例吗?

Med*_*Man 0 c# linq

我有一份建筑清单.每个建筑物都有一个人员清单.我在建筑物里寻找约翰.

假设传统搜索可能如下所示:

List<Building> Buildings = CreateBuildings();
foreach(Building building in Buildings)
{
    foreach(Person person in building.PersonList)
    {
         if (person.Name == "John")
         {
             return person;
         }
    }
}
Run Code Online (Sandbox Code Playgroud)

也正因为我们可以,这是否意味着我们应该?那么这是对LINQ的反模式/滥用吗?

Jon*_*eet 6

看起来像:

var query = from building in Buildings
            from person in building.PersonList
            where person.Name == "John"
            select person;
Run Code Online (Sandbox Code Playgroud)

该查询将查找名为"John"的所有人.如果您想要第一个这样的人,或者如果找不到这样的人就为null,您可以使用:

var john = query.FirstOrDefault();
Run Code Online (Sandbox Code Playgroud)

请注意,使用扩展方法可以让这个查询稍微更有效:

var query = Buildings.SelectMany(x => x.PersonList)
                     .Where(x => x.Name == "John");
Run Code Online (Sandbox Code Playgroud)

或者对于"第一个或默认"版本,您可以在一个步骤中做得更好(再次,非常轻微):

var john = Buildings.SelectMany(x => x.PersonList)
                    .FirstOrDefault(x => x.Name == "John");
Run Code Online (Sandbox Code Playgroud)

这些选项将避免使用查询表达式用于配对(人,构建)的自动生成的匿名类型.

是的,这对LINQ 来说是完全有效的用途 - 它正是它的设计目的.

  • @digEmAll:不,第一个版本被翻译成SelectMany,它将每对结果转换为匿名类型的实例.在我们的例子中,我们并不关心`building`,因此没有必要进行投影并创建我们不需要的对象.然后将另一个投影从匿名类型保存回查询表达式末尾的人员. (2认同)