{"record":{"id":"8372e2f330ed2f3b","repo":"dotnet/wpf","slug":"notsupportedexception-glyphrun","errorCode":null,"errorMessage":"NotSupportedException","messagePattern":"NotSupportedException","errorType":"exception","errorClass":"NotSupportedException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/GlyphRun.cs","lineNumber":2093,"sourceCode":"        }\n\n\n        /// <summary>\n        /// This class implements behavior of a Boolean list that contains all true values.\n        /// This allows us to have a single code path in hit testing API.\n        /// </summary>\n        private class DefaultCaretStopList : IList<bool>\n        {\n            public DefaultCaretStopList(int codePointCount)\n            {\n                _count = codePointCount + 1;\n            }\n\n            #region IList<bool> Members\n\n            public int IndexOf(bool item)\n            {\n                throw new NotSupportedException();\n            }\n\n            public void Insert(int index, bool item)\n            {\n                throw new NotSupportedException();\n            }\n\n            public bool this[int index]\n            {\n                get\n                {\n                    return true;\n                }\n                set\n                {\n                    throw new NotSupportedException();\n                }\n            }","sourceCodeStart":2075,"sourceCodeEnd":2111,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/GlyphRun.cs#L2075-L2111","documentation":"The nested GlyphRun caret-stop list implementation (GlyphRun.CaretStopsList, an IList<bool> adapter over an internal BitArray) does not support IndexOf and throws NotSupportedException unconditionally. The adapter exists only to expose CaretStops for reading by index and enumerating.","triggerScenarios":"Calling caretStops.IndexOf(true/false) on GlyphRun.CaretStops, e.g. LINQ IndexOf or code searching for the first enabled caret stop.","commonSituations":"LINQ-heavy text editing code assuming any IList<bool> supports IndexOf; searching caret stops to find the nearest boundary instead of using GlyphRun's FindNearestCaretStop-based APIs.","solutions":["Replace IndexOf with a manual for-loop over indices 0..Count-1 testing caretStops[i].","Copy to an array or List<bool> (CopyTo/ToList) and call IndexOf on that.","Prefer GlyphRun's caret APIs (GetNextCaretCharacterHit/GetPreviousCaretCharacterHit) which handle stop lookup internally."],"exampleFix":"// before\nint firstStop = run.CaretStops.IndexOf(true);\n// after\nint firstStop = -1;\nfor (int i = 0; i < run.CaretStops.Count; i++)\n    if (run.CaretStops[i]) { firstStop = i; break; }","handlingStrategy":"type-guard","validationCode":"int firstStop = -1;\nfor (int i = 0; i < caretStops.Count; i++) { if (caretStops[i]) { firstStop = i; break; } }","typeGuard":"bool SupportsIndexOf<T>(IList<T> list) => !(list.GetType().Name.Contains(\"CaretStopsList\")) && list.GetType().GetMethod(nameof(IList<T>.IndexOf)) != null;","tryCatchPattern":"try { idx = caretStops.IndexOf(true); }\ncatch (NotSupportedException) { idx = Enumerable.Range(0, caretStops.Count).FirstOrDefault(i => caretStops[i], -1); }","preventionTips":["Assume GlyphRun's exposed IList members are read/lookup adapters only.","Use indexed loops or CopyTo instead of IndexOf/Insert/Remove on CaretStops.","Prefer GlyphRun's caret navigation APIs over manual stop searches."],"tags":["wpf","glyphrun","not-supported","ilist"],"backgroundTag":"unsupported-operation","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"}