How to create IEnumerable to get all X lazily in one statement

C # does not allow lambda functions to represent iterator blocks (for example, there is no "return return" allowed inside a lambda function). If I wanted to create a lazy enumeration that would bring all disks during enumeration, for example, I would like to do something like

IEnumerable<DriveInfo> drives = {foreach (var drive in DriveInfo.GetDrives()) yield return drive;}; 

This took some time, but I figured it out as a way to get this functionality:

 var drives = Enumerable.Range(0, 1).SelectMany(_ => DriveInfo.GetDrives()); 

Is there a more idiomatic way?

+6
source share
2 answers

Why not write your own method, for example:

 public static IEnumerable<T> GetLazily<T>(Func<IEnumerable<T>> getSource) { foreach (var t in getSource()) yield return t; } 

or

 public static IEnumerable<T> GetLazily<T>(Func<IEnumerable<T>> getSource) { return (new int[1]).SelectMany(_ => getSource()); } 

This should allow use as follows:

 var drives = GetLazily(DriveInfo.GetDrives); 
+1
source
  var drives = new Func<IEnumerable<DriveInfo>>(DriveInfo.GetDrives); foreach(var drive in drives()) Console.WriteLine(drive); 

This decision has an important function; He acknowledges that multiple enumerations can be potentially bad. For example, a basic counter can snap-shot from a list, and then only ever list more than the list. There were other discussions about multiple transfers. See Answers here and here.

+1
source

Source: https://habr.com/ru/post/954352/


All Articles