如何在Linq查询中使用收益率

Gra*_*zer 2 c# linq yield

我有以下方法:

    public string GetDepartmentTitle(string DepartmentAbbreviation) {
        List<TaxonomyItem> Divisions = TaxonomyFromCMS.GetAllItems(DomainDataConstants.DivisionAndDepartment.TAXONOMY_ID);
        List<TaxonomyItem> Departments = new List<TaxonomyItem>();

        Divisions.ForEach(delegate(TaxonomyItem Division) {
            Departments.AddRange(Division.SubTaxonomyItems);
        });

        TaxonomyItem Result = (from d in Departments
                               where d.Name == DepartmentAbbreviation
                               select d).FirstOrDefault();

        return Result == null ? "" : Result.Title;
    }
Run Code Online (Sandbox Code Playgroud)

它首先读取所有的Divisons(只有3个),但是这些Divisions下面有许多Departments作为SubTaxonomyItems.目前,我逐步完成每个部门并提取出每个部门,并将它们放入名为Departments的列表中.然后我使用Linq搜索特定项目.

它工作得很好,但我很想跳过/消耗获得子项目的第一步.我尝试过以下似乎不起作用的行:

TaxonomyItem Result = (from d in Departments.SubTaxonomyItems
Run Code Online (Sandbox Code Playgroud)

然后我通过某种类型的lambda与Departments.SubTaxonomyItems的foreach包含一个yeild语句.这可能是诀窍,但我无法让它发挥作用.看看yeild语句,如果我做一些扩展方法似乎有办法.但我想知道它是否可以内联完成,并且像下面的伪代码一样:

    public string GetDepartmentTitle(string DepartmentAbbreviation) {
        List<TaxonomyItem> Divisions = TaxonomyFromCMS.GetAllItems(DomainDataConstants.DivisionAndDepartment.TAXONOMY_ID);

        TaxonomyItem Result = (from d in Divisions.ForEach(delegate(TaxonomyItem Division) {
                                 yeild return Divison.SubTaxonomyItems;
                               }) AS Dps
                               where Dps.Name == DepartmentAbbreviation
                               select Dps).FirstOrDefault();

        return Result == null ? "" : Result.Title;
    }
Run Code Online (Sandbox Code Playgroud)

这可能是这种方式还是我没有看到的其他方式?甚至可以在没有扩展方法的情况下完成吗?

Eri*_*ert 12

首先,只需在查询中添加另一个"from"即可轻松解决问题:

var query = from division in divisions
            from department in division.Departments
            where department.Name == whatever
            select department;
Run Code Online (Sandbox Code Playgroud)

这正是你正在做的事情; 它从每个部门中选出部门序列,并将所有这些序列粘合在一起,形成一个长序列的部门.

这为您提供了"拼接一堆序列"场景的灵活语法.但更普遍的是,有时你遇到这种情况:

var bars = from foo in foos
           some complicated query logic here
           select foo.bar;
var abcs = from bar in bars
           some other query logic here
           select bar.abc;
Run Code Online (Sandbox Code Playgroud)

并且您想要弄清楚如何将其转换为单个查询.你可以这样做:

var abcs = from bar in (
               from foo in foos
               some complicated query logic here
               select foo.bar)
           some other query logic here
           select bar.abc;
Run Code Online (Sandbox Code Playgroud)

这是丑陋的,或者你可以这样做:

var abcs = from foo in foos
           some complicated query logic here
           select foo.bar into bar
           some other query logic here
           select bar.abc;
Run Code Online (Sandbox Code Playgroud)

这完全相同,但阅读起来更愉快.此语法称为"查询延续".

回答你的具体问题:在匿名方法或lambda中加入"yield return"是不合法的.这非常不幸,因为它非常有用.编译器为使匿名函数和迭代器块工作而执行的转换非常复杂,到目前为止,我们总是试图让它们完全协同工作.(也就是说,你可以将一个lambda放在一个迭代器块中,但是你不能把一个迭代器块放在一个lambda中.)我希望,但不要保证,有一天我们能够修复这个代码并且允许迭代器阻塞lambda.(请记住,Eric关于未来语言功能的思考仅适用于娱乐目的.)