H
Harlan Messinger
I wanted to write a class to encapsulate an enumeration of all the files
in a directory. I could just use
Directory.GetFiles(directoryPath, "*.*",
SearchOptions.SearchOption.AllDirectories);
but when hundreds of files are involved and the directory is on a remote
server this causes a substantial delay, so I wanted to design an
enumeration that would browse through the root directory and its
subdirectories incrementally as iteration took place.
So I tried this, having read up only briefly on how "yield" works:
public class DirectoryFileList : IEnumerable<string>
{
public string Root { get; set; }
public DirectoryFileList(string root)
{
Root = root;
}
public IEnumerator<string> GetEnumerator()
{
DirectoryFileEnumerator enumerator = new
DirectoryFileEnumerator();
enumerator.Root = this.Root;
}
System.Collections.IEnumerator
System.Collections.IEnumerable.GetEnumerator()
{
throw new NotImplementedException(); // to implement
}
}
public class DirectoryFileEnumerator : IEnumerator<string>
{
public string Root { get; private set; }
public string Current
{
get
{
foreach (string file in Directory.GetFiles(Root))
{
yield return file;
}
foreach (string subdirectory in
Directory.GetDirectories(Root, "*.*", SearchOption.AllDirectories))
{
foreach (string file in
Directory.GetFiles(subdirectory))
{
yield return file;
}
}
yield break;
}
}
}
But this produces a compiler error, because "The body of
'ListAspScripts.DirectoryFileEnumerator.Current.get' cannot be an
iterator block because 'string' is not an iterator interface type". What
I'm finding out from elsewhere is that my iterating code has to be in a
method that returns an IEnumerable. From what I now read when I look
more closely, this code that returns one string after another has to be
in a method that returns IEnumerable<string>!
Well, that stinks. I can imagine wanting to retrieve all the files in a
directory in this manner in a variety of applications, and I would like
to encapsulate in a class, decoupled from any other class that might use
it! Now it looks as though I have to define a method in the class that
needs such an enumeration to return that enumeration. Am I missing
another approach?
in a directory. I could just use
Directory.GetFiles(directoryPath, "*.*",
SearchOptions.SearchOption.AllDirectories);
but when hundreds of files are involved and the directory is on a remote
server this causes a substantial delay, so I wanted to design an
enumeration that would browse through the root directory and its
subdirectories incrementally as iteration took place.
So I tried this, having read up only briefly on how "yield" works:
public class DirectoryFileList : IEnumerable<string>
{
public string Root { get; set; }
public DirectoryFileList(string root)
{
Root = root;
}
public IEnumerator<string> GetEnumerator()
{
DirectoryFileEnumerator enumerator = new
DirectoryFileEnumerator();
enumerator.Root = this.Root;
}
System.Collections.IEnumerator
System.Collections.IEnumerable.GetEnumerator()
{
throw new NotImplementedException(); // to implement
}
}
public class DirectoryFileEnumerator : IEnumerator<string>
{
public string Root { get; private set; }
public string Current
{
get
{
foreach (string file in Directory.GetFiles(Root))
{
yield return file;
}
foreach (string subdirectory in
Directory.GetDirectories(Root, "*.*", SearchOption.AllDirectories))
{
foreach (string file in
Directory.GetFiles(subdirectory))
{
yield return file;
}
}
yield break;
}
}
}
But this produces a compiler error, because "The body of
'ListAspScripts.DirectoryFileEnumerator.Current.get' cannot be an
iterator block because 'string' is not an iterator interface type". What
I'm finding out from elsewhere is that my iterating code has to be in a
method that returns an IEnumerable. From what I now read when I look
more closely, this code that returns one string after another has to be
in a method that returns IEnumerable<string>!
Well, that stinks. I can imagine wanting to retrieve all the files in a
directory in this manner in a variety of applications, and I would like
to encapsulate in a class, decoupled from any other class that might use
it! Now it looks as though I have to define a method in the class that
needs such an enumeration to return that enumeration. Am I missing
another approach?