{"record":{"id":"7af19e67e74f177b","repo":"dotnet/wpf","slug":"sr-format-sr-propertyisimmutable-datatype-this-gettype-name","errorCode":null,"errorMessage":"SR.Format(SR.PropertyIsImmutable, \"DataType\", this.GetType().Name)","messagePattern":"SR\\.Format\\(SR\\.PropertyIsImmutable, \"DataType\", this\\.GetType\\(\\)\\.Name\\)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/TemplateKey.cs","lineNumber":71,"sourceCode":"            _initializing = false;\n        }\n\n#endregion ISupportInitialize\n\n        /// <summary>\n        /// The type for which the template is designed.  This is either\n        /// a Type (for object data), or a string (for XML data).  In the latter\n        /// case the string denotes the XML tag name.\n        /// </summary>\n        public object DataType\n        {\n            get { return _dataType; }\n            set\n            {\n                if (!_initializing)\n                    throw new InvalidOperationException(SR.Format(SR.PropertyIsInitializeOnly, \"DataType\", this.GetType().Name));\n                if (_dataType != null && value != _dataType)\n                    throw new InvalidOperationException(SR.Format(SR.PropertyIsImmutable, \"DataType\", this.GetType().Name));\n\n                Exception ex = ValidateDataType(value, \"value\");\n                if (ex != null)\n                    throw ex;\n\n                _dataType = value;\n            }\n        }\n\n        /// <summary> Override of Object.GetHashCode() </summary>\n        public override int GetHashCode()\n        {\n            // note that the hash code can change, but only during intialization\n            // and only once (DataType can only be changed once, from null to\n            // non-null, and that can only happen during [Begin/End]Init).\n            // Technically this is still a violation of the \"constant during\n            // lifetime\" rule, however in practice this is acceptable.  It is\n            // very unlikely that someone will put a TemplateKey into a hashtable","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/TemplateKey.cs#L53-L89","documentation":"Within an initialization block, DataType may be set once; a second assignment to a different value throws InvalidOperationException with the PropertyIsImmutable message. Template keys hash and compare on DataType, so changing it after it is established would corrupt template lookup semantics.","triggerScenarios":"Calling BeginInit(), assigning DataType = typeof(A), then assigning DataType = typeof(B) before EndInit().","commonSituations":"Retry/reconfiguration loops that apply defaults then overwrite with the real value; generic property-setting frameworks that assign every property including already-set ones.","solutions":["Assign DataType exactly once per initialization block.","Guard with 'if (key.DataType == null)' before assigning inside the initialization block.","Instantiate a new TemplateKey for each distinct DataType."],"exampleFix":"// before\nkey.BeginInit();\nkey.DataType = typeof(A);\nkey.DataType = typeof(B); // throws\n// after\nkey.BeginInit();\nif (key.DataType == null)\n    key.DataType = typeof(B);\nkey.EndInit();","handlingStrategy":"type-guard","validationCode":"if (key.DataType != value)\n{\n    key.BeginInit();\n    key.DataType = value;\n    key.EndInit();\n}","typeGuard":"bool CanAssign(TemplateKey key, object value) => key.DataType == null || key.DataType == value;","tryCatchPattern":"try { key.DataType = value; }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"immutable\")) { /* skip, already set */ }","preventionTips":["Assign each property at most once per initialization block.","Centralize key construction in one factory method.","Avoid generic property-copying that may double-assign DataType."],"tags":["wpf","immutability","initialization"],"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-21T21:30:21.729Z"}