【问题标题】:Unable to step into or break in method called inside Linq query/expression无法进入或中断在 Linq 查询/表达式中调用的方法
【发布时间】:2015-04-10 07:59:54
【问题描述】:

我在尝试进入从 Linq 查询中调用的方法时遇到了一个奇怪的问题(尽管我在使用 Linq 表达式时也遇到了这个问题)。代码编译,它似乎可以工作(我得到了我期望的结果)。

IEnumerable<TagBuilder> theOutcome = from r in resultSet
                                     select GetTableDataRow(null);

IEnumerable<TagBuilder> theOutcome = resultSet.Select(r => GetTableDataRow(null));

被调用的方法定义如下:

private static TagBuilder GetTableDataRow(IEnumerable<object> rowData)
{
    TagBuilder tr = new TagBuilder("tr");
    return tr;
}

resultSet 变量是一个包含两个项目的IPagedList

变量theOutcome 最终按预期持有两个TagBuilder 实例。

但是,即使我在有问题的 Linq 查询上或之前设置了断点,我也无法进入 GetTableDataRow()。如果我在 GetTableDataRow() 方法中设置断点,它也永远不会命中。

我完全被难住了。任何人都可以帮忙吗?代码现在显然非常简单,但我需要在开发时使用调试器逐步完成该方法的内容。

【问题讨论】:

    标签: c# linq visual-studio-2013 ienumerable pagedlist


    【解决方案1】:

    您需要计算表达式。

    只需调用ToArray()ToList()Count()IEnumerable&lt;T&gt; 上的任何其他强制评估的方法或扩展。

    Select 的结果是使用 deferred execution 评估的,因此在使用查询之前,GetTableDataRow 不会发生任何事情。


    更明确地说,您可以通过扩展 Select 的功能来了解这一点:

    IEnumerable<TagBuilder> theOutcome = resultSet.Select(r => GetTableDataRow(null));
    

    等价于

    IEnumerable<TagBuilder> theOutcome = getRows(resultSet);
    

    getRows 在哪里:

    IEnumerable<TagBuilder> getRows(IEnumerable<IPagedList> source)
    {
        foreach ( IPagedListitem in source )
            yield return GetTableDataRow(null);
    }
    

    因为GetTableDataRowyield 返回的,所以在强制评估之前不会对其进行评估(例如,通过ToArray() 等)。

    【讨论】:

    • .ToArray() 放在Select 的末尾确实允许我进入该方法!我看了你链接的文章,但我真的不明白惰性评估与这个问题的关系,从某种意义上说,不是因为我将输出到 theOutcome 变量而正在评估 Linq?看起来你现在已经把它编辑掉了,所以也许它毕竟不相关。不过,我很想知道发生了什么。
    • 我编辑了它,因为它不是一个相关的链接...我已经编辑了我的答案,以获得更好的链接。
    • 当您在问题中说 TheOutcome 变量最终按预期持有两个 TagBuilder 实例 时,调试器正在评估可枚举...
    猜你喜欢
    • 2022-11-02
    • 1970-01-01
    • 2021-05-28
    • 2023-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多