c# – 是否可以缓存IEnumerable延迟评估结果?
发布时间:2020-12-15 21:02:05 所属栏目:百科 来源:网络整理
导读:我正在研究一种查找配置文件路径的方法.这需要进行两次传递:首先查找任何现有的配置文件,然后返回并找到第一个可写路径. 虽然我的特殊情况有些过分,但这让我想到:是否可以同时进行懒惰评估并防止多次枚举? 为了说明我的意思,请考虑以下代码: public IEnu
我正在研究一种查找配置文件路径的方法.这需要进行两次传递:首先查找任何现有的配置文件,然后返回并找到第一个可写路径.
虽然我的特殊情况有些过分,但这让我想到:是否可以同时进行懒惰评估并防止多次枚举? 为了说明我的意思,请考虑以下代码: public IEnumerable<string> GetPaths() { Console.WriteLine("GetPaths() Returning 'one'"); yield return "one"; Console.WriteLine("GetPaths() Returning 'two'"); yield return "two"; Console.WriteLine("GetPaths() Returning 'three'"); yield return "three"; } public bool IsWritable(string path) => false; // testing only 如果我跑: var paths = GetPaths(); Console.WriteLine("Searching for existing file.."); foreach (var path in paths) { if (File.Exists(path)) { Console.WriteLine($"Found existing file '{path}'"); } } Console.WriteLine("Searching for a writable path.."); foreach (var path in paths.Reverse()) // NOTE: paths enumarated twice { if (IsWritable(path)) { Console.WriteLine($"Found writable path '{path}'"); } } Console.WriteLine("No paths found"); 如果文件’one’存在,我们得到: Searching for existing file.. Returning 'one' Found existing file 'one' 但是,如果没有文件存在,我们得到: Searching for existing file.. Returning 'one' Returning 'two' Returning 'three' Searching for a writable path.. Returning 'one' Returning 'two' Returning 'three' No paths found (我们两次浪费地枚举GetPaths()的结果) 一个简单的解决方法是将第一行更改为: var paths = GetPaths().ToList(); 但是,这意味着即使文件存在,输出也将是: Returning 'one' Returning 'two' Returning 'three' Searching for existing file.. Found existing file 'one' (如我们不必要地枚举列表的其余部分) 是否有(内置)方法来获取延迟枚举并仍然阻止多次枚举? 换句话说,’one’存在时所需的输出是: Searching for existing file.. Returning 'one' Found existing file 'one' 如果没有文件: Searching for existing file.. Returning 'one' Returning 'two' Returning 'three' Searching for a writable path.. No paths found 解决方法
就在这里.如果您的Lazy调用返回的Enumerator从基础数据提供程序的同一实例依次获取其数据,并且该提供程序跟踪它产生的每个项目,那么Enumerator的所有实例实际上都是从数据提供程序的同一实例中提取数据.
考虑一个Enumerator来从文件中返回行;如果该枚举器与该文件的所有其他枚举器共享相同的Stream实例,那么您将获得您所说明的行为. 在伪代码中 static System.IO.FileStream fs; private static void GetFileStream() { if(fs == null) fs = System.IO.File.Open(....); return fs; } public Enumarable<string> GetLines() { // return an enumerator that uses the result of GetFileStream() and // advances the file pointer. All Enumerables returned by this method // will return unique lines from the same file } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |