[SOLVED] .NET creating an IEnumerator on top of “GetEnumerator()” method from another class

Issue

This Content is from Stack Overflow. Question asked by JobaDiniz

I’m trying to create an IEnumerator based on the Directory.EnumerateFiles as you can see below. My enumerator works on top of Directory.EnumerateFiles by using LINQ .Select to convert the FileInfo into a specialized class MyFile.

    struct Enumerator : IEnumerator<MyFile>
    {
        private readonly Lazy<IEnumerator<MyFile>> enumerator;

        public Enumerator(DirectoryInfo directory)
        {
            enumerator = new Lazy<IEnumerator<MyFile>>(() =>
            {
                return directory
                .EnumerateFiles($"*{MyFile.Extension}", SearchOption.TopDirectoryOnly)
                .OrderBy(f => f.Name)
                .Select(MyFile.Read)
                .GetEnumerator();
            });
        }

        WalFile IEnumerator<MyFile>.Current => enumerator.Value.Current;
        object IEnumerator.Current => enumerator.Value.Current;
        void IDisposable.Dispose() => enumerator.Value.Dispose();
        bool IEnumerator.MoveNext() => enumerator.Value.MoveNext();
        void IEnumerator.Reset() => enumerator.Value.Reset();
    }

But it only works when I iterate once. If I iterate the enumerator twice, the 2nd time it’s empty. Even removing the Lazy, it doesn’t change the result.

This IEnumerator is used in another class such as MyFileCollection : IEnumerable<MyFile>, where I implement IEnumerable with the specialized Enumerator class above.

Any insights to be this right?



Solution

Instead of writing a custom enumerator, you could just use the following method:

public IEnumerable<MyFile> EnumerateFiles(DirectoryInfo directory)
{
  return directory
    .EnumerateFiles($"*{MyFile.Extension}", SearchOption.TopDirectoryOnly)
    .OrderBy(f => f.Name)
    .Select(MyFile.Read);
}

This is much simpler than creating an enumerator from scratch; if you need the code in various places, you can implement it in a helper class that you inject into the classes that rely on it. This is especially a good way if you need to mock the code in unit tests. If this does not matter, you can also make it a static helper method or an extension method to DirectoryInfo.


This Question was asked in StackOverflow by JobaDiniz and Answered by Markus It is licensed under the terms of CC BY-SA 2.5. - CC BY-SA 3.0. - CC BY-SA 4.0.

people found this article helpful. What about you?