{"record":{"id":"55fdc42d1ea1fc11","repo":"dotnet/wpf","slug":"sr-notsupported-readonlycollection","errorCode":null,"errorMessage":"SR.NotSupported_ReadOnlyCollection","messagePattern":"SR\\.NotSupported_ReadOnlyCollection","errorType":"exception","errorClass":"NotSupportedException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Collections/ObjectModel/WeakReadOnlyCollection.cs","lineNumber":81,"sourceCode":"\n        /*\n        protected IList<T> Items {\n            get {\n                return list;\n            }\n        }\n        */\n\n        bool ICollection<T>.IsReadOnly {\n            get { return true; }\n        }\n\n        T IList<T>.this[int index] {\n            //get { return list[index]; }\n            get { return (T)list[index].Target; }\n            set {\n                //ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);\n                throw new NotSupportedException(SR.NotSupported_ReadOnlyCollection);\n            }\n        }\n\n        void ICollection<T>.Add(T value) {\n            //ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);\n            throw new NotSupportedException(SR.NotSupported_ReadOnlyCollection);\n        }\n\n        void ICollection<T>.Clear() {\n            //ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);\n            throw new NotSupportedException(SR.NotSupported_ReadOnlyCollection);\n        }\n\n        void IList<T>.Insert(int index, T value) {\n            //ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);\n            throw new NotSupportedException(SR.NotSupported_ReadOnlyCollection);\n        }\n","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Collections/ObjectModel/WeakReadOnlyCollection.cs#L63-L99","documentation":"WeakReadOnlyCollection is, by contract, read-only: its IList<T> indexer's setter always throws NotSupportedException with SR.NotSupported_ReadOnlyCollection. The collection wraps weak references (this getter resolves list[index].Target), so mutating it through the read-only view is never allowed. Any write through the IList<T> interface fails unconditionally.","triggerScenarios":"Assigning through the indexer of a WeakReadOnlyCollection cast to IList<T>, e.g. ((IList<T>)weakCollection)[i] = item, or via code that accepts IList<T> and writes into it.","commonSituations":"Passing the read-only wrapper to helper methods that take IList<T> and mutate in place (sorting, updating, filling); assuming a read-only wrapper supports index assignment; old code refactored from a mutable List<T> to a read-only view.","solutions":["Don't mutate the read-only view: rebuild a new collection/list and replace the reference instead of writing in place.","If mutation is needed, keep the underlying mutable collection and wrap it only for read-only consumers.","Check for IReadOnlyList<T>/ReadOnlyCollection APIs instead of casting to IList<T> and writing.","Guard generic IList<T>-accepting helpers with IsReadOnly before writing (IList.IsReadOnly returns true here)."],"exampleFix":"// before\nvar list = (IList<string>)weakReadOnly;\nlist[0] = \"new\"; // NotSupportedException\n// after\nif (list.IsReadOnly) throw new InvalidOperationException(\"collection is read-only\");\nvar copy = new List<string>(weakReadOnly);\ncopy[0] = \"new\";","handlingStrategy":"type-guard","validationCode":"if (((IList<T>)collection).IsReadOnly)\n    throw new InvalidOperationException(\"Cannot write into a read-only collection; build a new one instead.\");","typeGuard":"bool IsWritable<T>(ICollection<T> c) => c is not WeakReadOnlyCollection<T> && !c.IsReadOnly;","tryCatchPattern":"try\n{\n    ((IList<T>)collection)[index] = item;\n}\ncatch (NotSupportedException)\n{\n    var copy = new List<T>(collection);\n    copy[index] = item;\n    ReplaceCollection(copy);\n}","preventionTips":["Treat ReadOnly*/weak read-only wrappers as immutable; never cast down to IList<T> to write","Expose IReadOnlyList<T> instead of IList<T> in your APIs to prevent accidental writes","Prefer copy-on-write: build a new collection and swap the reference","Check ICollection<T>.IsReadOnly in generic helpers before mutating"],"tags":["read-only-collection","unsupported-operation","collections","csharp"],"backgroundTag":"unsupported-operation","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}