{"record":{"id":"61b40442cab3f7a3","repo":"dotnet/wpf","slug":"sr-enumeratorreachedend-grid","errorCode":null,"errorMessage":"SR.EnumeratorReachedEnd","messagePattern":"SR\\.EnumeratorReachedEnd","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/Grid.cs","lineNumber":3976,"sourceCode":"                    }\n                    _currentEnumerator++;\n                }\n                return (false);\n            }\n\n            public Object Current\n            {\n                get\n                {\n                    if (_currentEnumerator == -1)\n                    {\n                        // IEnumerator.Current is documented to throw this exception\n                        throw new InvalidOperationException(SR.EnumeratorNotStarted);\n                    }\n                    if (_currentEnumerator >= 3)\n                    {\n                        // IEnumerator.Current is documented to throw this exception\n                        throw new InvalidOperationException(SR.EnumeratorReachedEnd);\n                    }\n\n                    //  assert below is not true anymore since UIElementCollection allowes for null children\n                    //Debug.Assert(_currentChild != null);\n                    return (_currentChild);\n                }\n            }\n\n            public void Reset()\n            {\n                _currentEnumerator = -1;\n                _currentChild = null;\n                _enumerator0.Reset();\n                _enumerator1.Reset();\n                _enumerator2Index = 0;\n            }\n\n            private int _currentEnumerator;","sourceCodeStart":3958,"sourceCodeEnd":3994,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/Grid.cs#L3958-L3994","documentation":"Grid's child enumerator's Current property throws InvalidOperationException (SR.EnumeratorReachedEnd) when Current is read after enumeration has finished (_currentEnumerator >= 3). Per the IEnumerator contract, Current is invalid once MoveNext() has returned false.","triggerScenarios":"Calling MoveNext() until it returns false and then reading Current again; continuing to dereference a stored enumerator after the loop completed; reading Current after calling Reset-less exhausted enumeration across Grid children/row/column definition sets.","commonSituations":"Loop helpers that cache Current after the loop ends; retrying enumeration without calling Reset(); generic enumeration wrappers that read Current unconditionally after MoveNext fails.","solutions":["Only access Current inside the loop while MoveNext() returns true.","Capture the last value inside the loop instead of reading Current afterwards.","Call Reset() (or get a new enumerator) before re-enumerating an exhausted enumerator."],"exampleFix":"// before\nwhile (e.MoveNext()) { }\nvar last = e.Current; // InvalidOperationException\n// after\nobject last = null;\nwhile (e.MoveNext())\n{\n    last = e.Current;\n}","handlingStrategy":"validation","validationCode":"object last = null; while (e.MoveNext()) { last = e.Current; } // never read Current after loop","typeGuard":"bool CanReadCurrent(IEnumerator e) => e.MoveNext(); // re-check before each Current access","tryCatchPattern":"try { var cur = e.Current; }\ncatch (InvalidOperationException) { /* enumeration exhausted; capture values inside the loop instead */ }","preventionTips":["Capture Current inside the MoveNext loop","Don't cache and read Current after enumeration ends","Call Reset or acquire a new enumerator for reuse"],"tags":["wpf","grid","enumerator","ienumerable","invalid-operation"],"backgroundTag":"invalid-state-transition","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-22T01:17:13.364Z"}