{"record":{"id":"48c8fa5d0f8aa9ab","repo":"PrismLibrary/Prism","slug":"operation-not-supported-for-the-given-expression-type-only","errorCode":null,"errorMessage":"Operation not supported for the given expression type. Only MemberExpression and ConstantExpression are currently supported.","messagePattern":"Operation not supported for the given expression type\\. Only MemberExpression and ConstantExpression are currently supported\\.","errorType":"exception","errorClass":"NotSupportedException","httpStatus":null,"severity":"error","filePath":"src/Prism.Core/Commands/PropertyObserver.cs","lineNumber":38,"sourceCode":"            _action = action;\n            SubscribeListeners(propertyExpression);\n        }\n\n        private void SubscribeListeners(Expression? propertyExpression)\n        {\n            var propNameStack = new Stack<PropertyInfo>();\n            while (propertyExpression is MemberExpression temp) // Gets the root of the property chain.\n            {\n                propertyExpression = temp.Expression;\n\n                if (temp.Member is PropertyInfo propertyInfo)\n                {\n                    propNameStack.Push(propertyInfo); // Records the member info as property info\n                }\n            }\n\n            if (propertyExpression is not ConstantExpression constantExpression)\n                throw new NotSupportedException(\"Operation not supported for the given expression type. \" +\n                                                \"Only MemberExpression and ConstantExpression are currently supported.\");\n\n            var propObserverNodeRoot = new PropertyObserverNode(propNameStack.Pop(), _action);\n            PropertyObserverNode previousNode = propObserverNodeRoot;\n            foreach (var propName in propNameStack) // Create a node chain that corresponds to the property chain.\n            {\n                var currentNode = new PropertyObserverNode(propName, _action);\n                previousNode.Next = currentNode;\n                previousNode = currentNode;\n            }\n\n            object? propOwnerObject = constantExpression.Value;\n\n            if (propOwnerObject is not INotifyPropertyChanged inpcObject)\n                throw new InvalidOperationException(\"Tried to subscribe to PropertyChanged in the object that \" +\n                                                    $\"defines the '{propObserverNodeRoot.PropertyInfo.Name}' property, but the object does not implement INotifyPropertyChanged.\");\n\n            propObserverNodeRoot.SubscribeListenerFor(inpcObject);","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/PrismLibrary/Prism/blob/358118cd640d9a22ff8cf21c8ad197fa038b7990/src/Prism.Core/Commands/PropertyObserver.cs#L20-L56","documentation":"PropertyObserver builds a subscription chain from a property expression like () => obj.A.B, but it only understands MemberExpression and ConstantExpression nodes. Passing any other expression kind (method calls, binary expressions, conversions beyond member chains) causes this NotSupportedException.","triggerScenarios":"Calling PropertyObserver.Create(() => x.GetFoo().Bar), (() => a + b), or any lambda whose body is not a chain of member accesses ending in a constant root; thrown from SubscribeListeners during observation setup.","commonSituations":"Developers try to observe computed properties via method calls or use expression bodies with operators, assuming arbitrary expression trees are supported.","solutions":["Rewrite the lambda as a plain member chain ending at a field/property of a concrete object, e.g. () => vm.Inner.Name","Evaluate the intermediate value yourself and observe the resulting object's property","Subscribe manually to PropertyChanged for non-member-chain scenarios"],"exampleFix":"// before\nPropertyObserver.Create(() => vm.CalculateTotal().Amount);\n// after\nPropertyObserver.Create(() => vm.TotalAmount);","handlingStrategy":"validation","validationCode":"var body = ((LambdaExpression)expr).Body;\nbool ok = body is MemberExpression || body is ConstantExpression;\n// only pass expressions whose body is a member/constant chain","typeGuard":"static bool IsSupportedPropertyExpression<T>(Expression<Func<T>> e) => e.Body is MemberExpression || e.Body is ConstantExpression;","tryCatchPattern":"try { observer = PropertyObserver.Create(expr); }\ncatch (NotSupportedException) { /* fall back to manual PropertyChanged subscription */ }","preventionTips":["Use only plain member-chain lambdas: () => a.B.C","Avoid method calls, operators, or casts inside observed expressions","Inspect the expression body type before handing it to PropertyObserver"],"tags":["prism","expression-tree","propertyobserver","not-supported"],"backgroundTag":"unsupported-operation","analyzedSha":"358118cd640d9a22ff8cf21c8ad197fa038b7990","analyzedAt":"2026-09-15T15:00:31.079Z","contentChangedAt":"2026-09-15T15:00:31.079Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}