{"record":{"id":"3d47fb28119f2178","repo":"dotnet/wpf","slug":"sr-enumerator-notstarted-point3dcollection","errorCode":null,"errorMessage":"SR.Enumerator_NotStarted","messagePattern":"SR\\.Enumerator_NotStarted","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media3D/Generated/Point3DCollection.cs","lineNumber":868,"sourceCode":"            /// <summary>\n            /// Current element\n            ///\n            /// The behavior of IEnumerable&lt;T>.Current is undefined\n            /// before the first MoveNext and after we have walked\n            /// off the end of the list. However, the IEnumerable.Current\n            /// contract requires that we throw exceptions\n            /// </summary>\n            public Point3D Current\n            {\n                get\n                {\n                    if (_index > -1)\n                    {\n                        return _current;\n                    }\n                    else if (_index == -1)\n                    {\n                        throw new InvalidOperationException(SR.Enumerator_NotStarted);\n                    }\n                    else\n                    {\n                        Debug.Assert(_index == -2, \"expected -2, got \" + _index + \"\\n\");\n                        throw new InvalidOperationException(SR.Enumerator_ReachedEnd);\n                    }\n                }\n            }\n\n            #endregion\n\n            #region Data\n            private Point3D _current;\n            private Point3DCollection _list;\n            private uint _version;\n            private int _index;\n            #endregion\n        }","sourceCodeStart":850,"sourceCodeEnd":886,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media3D/Generated/Point3DCollection.cs#L850-L886","documentation":"Point3DCollection's enumerator Current property throws InvalidOperationException(SR.Enumerator_NotStarted) when Current is accessed before the first MoveNext() call (_index == -1). WPF generated enumerators only allow Current reads while positioned on a valid element.","triggerScenarios":"Reading e.Current immediately after GetEnumerator() without calling MoveNext(); reading Current in a while loop body before the first MoveNext returns true.","commonSituations":"Hand-written enumerator loops that inspect Current before advancing; refactorings that moved a Current read outside the loop condition.","solutions":["Call MoveNext() before reading Current","Use foreach, which guarantees MoveNext precedes Current access","Guard with a bool flag tracking whether MoveNext has succeeded"],"exampleFix":"// before\nvar e = collection.GetEnumerator();\nConsole.WriteLine(e.Current); // throws\n// after\nvar e = collection.GetEnumerator();\nif (e.MoveNext()) Console.WriteLine(e.Current);","handlingStrategy":"type-guard","validationCode":"bool canRead = enumeratorStarted; // true only after a MoveNext() returned true","typeGuard":"bool TryReadCurrent(System.Collections.IEnumerator e, out object? cur) { cur = null; if (e.MoveNext()) { cur = e.Current; return true; } return false; }","tryCatchPattern":"try { var cur = e.Current; }\ncatch (InvalidOperationException) { /* MoveNext not called yet; call MoveNext first */ }","preventionTips":["Always call MoveNext() before reading Current","Use foreach to avoid manual ordering mistakes","Track enumerator state with a bool when hand-rolling loops"],"tags":["wpf","enumeration","invalidoperation"],"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"}