Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create an IEnumerable to get all X lazily in a single statement

C# doesn't allow lambda functions to represent iterator blocks (e.g., no "yield return" allowed inside a lambda function). If I wanted to create a lazy enumerable that yielded all the drives at the time of enumeration for example, I'd like to do something like

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

It took a while, but I figured out this as a way to get that functionality:

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

Is there a more idiomatic way?

like image 216
Dax Fohl Avatar asked Sep 22 '13 14:09

Dax Fohl


1 Answers

Why not write your own method, something like:

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());
}

It ought to allow usage like this:

var drives = GetLazily(DriveInfo.GetDrives);
like image 104
Jeppe Stig Nielsen Avatar answered Oct 06 '22 01:10

Jeppe Stig Nielsen