{"record":{"id":"bc1895abfefcd721","repo":"dotnet/efcore","slug":"unary-node-with-non-null-method","errorCode":null,"errorMessage":"Unary node with non-null method","messagePattern":"Unary node with non-null method","errorType":"exception","errorClass":"NotImplementedException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Design/Query/Internal/LinqToCSharpSyntaxTranslator.cs","lineNumber":2478,"sourceCode":"            ExpressionType.TypeEqual\n                => BinaryExpression(SyntaxKind.EqualsExpression, visitedExpression, TypeOfExpression(Generate(node.TypeOperand))),\n\n            _ => throw new ArgumentOutOfRangeException()\n        };\n\n        return node;\n    }\n\n    /// <inheritdoc />\n    protected override Expression VisitUnary(UnaryExpression unary)\n    {\n        if (unary.Method is not null\n            && !unary.Method.IsHideBySig\n            && !unary.Method.IsSpecialName\n            && unary.Method.Name != \"op_Implicit\"\n            && unary.Method.Name != \"op_Explicit\")\n        {\n            throw new NotImplementedException(\"Unary node with non-null method\");\n        }\n\n        using var _ = ChangeContext(ExpressionContext.Expression);\n\n        var operand = Translate<ExpressionSyntax>(unary.Operand);\n\n        // TODO: Confirm what to do with the checked expression types\n\n        Result = unary.NodeType switch\n        {\n            ExpressionType.Negate => _g.NegateExpression(operand),\n            ExpressionType.NegateChecked => _g.NegateExpression(operand),\n            ExpressionType.Not when unary.Type == typeof(bool) => _g.LogicalNotExpression(operand),\n            ExpressionType.Not => _g.BitwiseNotExpression(operand),\n            ExpressionType.OnesComplement => _g.BitwiseNotExpression(operand),\n            ExpressionType.IsFalse => _g.LogicalNotExpression(operand),\n            ExpressionType.IsTrue => operand,\n            ExpressionType.ArrayLength => _g.MemberAccessExpression(operand, \"Length\"),","sourceCodeStart":2460,"sourceCodeEnd":2496,"githubUrl":"https://github.com/dotnet/efcore/blob/dbf9771522148d61a2467854921bd5dc6f6e6916/src/EFCore.Design/Query/Internal/LinqToCSharpSyntaxTranslator.cs#L2460-L2496","documentation":"VisitUnary handles standard unary operators and user-defined conversions (op_Implicit/op_Explicit). A UnaryExpression carrying an arbitrary backing Method that is not a conversion and not a special-name/hide-by-sig operator cannot be rendered, so it throws NotImplementedException.","triggerScenarios":"A UnaryExpression with a custom Method that is neither op_Implicit/op_Explicit nor an IsSpecialName/IsHideBySig operator method.","commonSituations":"Hand-built unary expressions with custom operator methods; unusual operator overloads attached to unary nodes.","solutions":["Use standard unary operators built by the C# compiler rather than attaching custom methods.","If you have a custom conversion, implement it as op_Implicit/op_Explicit so it is recognized.","Replace the custom-method unary with an explicit method call."],"exampleFix":"// before\nvar u = Expression.MakeUnary(ExpressionType.Negate, operand, null, customMethodInfo);\n// after\nvar u = Expression.Negate(operand); // standard operator, no custom method","handlingStrategy":"validation","validationCode":"protected override Expression VisitUnary(UnaryExpression u) {\n    if (u.Method is not null && !u.Method.IsSpecialName && !u.Method.IsHideBySig\n        && u.Method.Name != \"op_Implicit\" && u.Method.Name != \"op_Explicit\") Found = true;\n    return u;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use standard unary operators produced by the C# compiler.","Implement custom conversions as op_Implicit/op_Explicit.","Replace custom-method unary nodes with explicit method calls."],"tags":["ef-core","linq","expression-tree","unary","operators"],"analyzedSha":"dbf9771522148d61a2467854921bd5dc6f6e6916","analyzedAt":"2026-08-06T20:46:03.226Z","schemaVersion":2},"datasetVersion":"2026-08-07T02:17:10.218Z"}