为啥将结果添加到 List 时不执行方法调用?

Posted

技术标签:

【中文标题】为啥将结果添加到 List 时不执行方法调用?【英文标题】:Why isn't a method call executed when adding its result to a List?为什么将结果添加到 List 时不执行方法调用? 【发布时间】:2020-05-21 15:49:52 【问题描述】:

Repeat(item, nr))res.Add(Repeat(item, nr)) 一起添加到res 时,Repeat 方法不会执行。

为什么?我使用了一个调试器,它没有执行它。

public class Program

    public static IEnumerable<IEnumerable<T>> Echo<T>(IEnumerable<T> src, int nr)
    
        List<IEnumerable<T>> res = new List<IEnumerable<T>>();
        foreach (T item in src)
        
            Console.Write(item);
            res.Add(Repeat(item, nr));
        
        return res;
    

    static IEnumerable<T> Repeat<T>(T item, int nr)
    
        for (int i = 0; i < nr; i++)
        
            Console.Write(item);
            yield return item;
        
    

    public static void Main()
    
        string[] src =  "a", "b", "c" ;
        Echo(src, 2);
    


【问题讨论】:

这就是迭代器方法的工作原理——它们生成IEnumerables,在有人调用GetEnumerator 并使用它之前不会做任何事情。 Repeat is 被调用,但唯一真正命中的是编译器生成的代码,它产生了 IEnumerable 实例,而不是迭代器方法的主体——所以调试器不显示该代码正在运行。 尝试将 .ToList() 添加到 Echo 行:Echo(src, 2).ToList(); @Neil 只会枚举 outer 集合 - 仍然不会枚举列表中的集合。您可以使用SelectMany().ToList() 枚举内部集合。 【参考方案1】:

使用yield return 构建的枚举器在被迭代之前不会被执行。因此,您需要一些代码来迭代添加到列表中的枚举器。由于您从未对 Echo 返回的枚举器执行任何操作(更不用说其中的项目),因此永远不会执行枚举器。

【讨论】:

以上是关于为啥将结果添加到 List 时不执行方法调用?的主要内容,如果未能解决你的问题,请参考以下文章

为啥非 const 方法是私有的时不调用公共 const 方法?

为啥 Python 在创建实例时不调用实例方法 __init__() 而是调用类提供的 __init__() ?

为啥numpy数组的astype方法在转换类型时不修改输入?

powermock mock静态方法为啥会执行

为啥 PHP $_SESSION 变量在 header() 方法中使用时不起作用?

hibernate多表联合查询返回的list没有数据,但list.isEmpty()判断为啥不为真