dotnet / dotnet/msbuild

Change ItemDictionary<T>.GetEnumerator() to iterator

Open
#7,286 6 comments 2 reactions 0 assignees View on GitHub
needs-design triaged
Dominant language
C#
Stars
5.5k
Forks
1.5k
Avg merge
1d 6h
Merged PRs (30d)
139

Description

[Microsoft.Build.Collections.ItemDictionary\.GetEnumerator()](https://github.com/dotnet/msbuild/blob/96a618ca59610908eddc92bfd0198746c34f0ed5/src/Build/Collections/ItemDictionary.cs#L154-L160) currently creates an instance of a nested Enumerator class. It could be rewritten as an iterator method with nested `foreach` loops and `yield return`.

Advantages:

- Source code becomes shorter and easier to understand.
- Ensures that Dispose is called at the appropriate places. (But it looks like a no-op anyway.)
- Gets rid of the custom IEnumerator.Reset() implementation that has a bug ().

Risks:

- Iterators throw NotSupportedException if IEnumerator.Reset() is called, unlike the current custom enumerator. However, the current implementation of IEnumerator.Reset() has a bug already, and ItemDictionary\ is internal, so perhaps nothing calls Reset.
- The [current implementation of IEnumerator.Current](https://github.com/dotnet/msbuild/blob/96a618ca59610908eddc92bfd0198746c34f0ed5/src/Build/Collections/ItemDictionary.cs#L422-L427) throws InvalidOperationException (by attempting to read `((IEnumerator)_listEnumerator).Current`) if there is no current element. An iterator would silently return the previous value of IEnumerator.Current instead. If some caller incorrectly reads IEnumerator.Current in such a situation, then an iterator might make that bug more difficult to find.
- Runtime performance might become slower, or faster.
- Debugging might become more difficult, as the compiler-generated state machine would be more complex than the source code.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.