{"record":{"id":"2512f1147c0fea22","repo":"dotnet/efcore","slug":"private-static-field-assignment","errorCode":null,"errorMessage":"Private static field assignment","messagePattern":"Private static field assignment","errorType":"exception","errorClass":"NotImplementedException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Design/Query/Internal/LinqToCSharpSyntaxTranslator.cs","lineNumber":1708,"sourceCode":"                _g.IdentifierName(unsafeAccessorDeclaration.Identifier.Text),\n                Translate<ExpressionSyntax>(memberExpression.Expression));\n    }\n\n    /// <summary>\n    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to\n    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in\n    ///     any release. You should only use it directly in your code with extreme caution and knowing that\n    ///     doing so can result in application failures when updating to a new Entity Framework Core release.\n    /// </summary>\n    protected virtual void TranslateNonPublicMemberAssignment(\n        MemberExpression memberExpression,\n        Expression value,\n        SyntaxKind assignmentKind)\n    {\n        // LINQ expression trees can directly access private members, but C# code cannot. Use the .NET [UnsafeAccessor] feature.\n        if (memberExpression.Expression is null)\n        {\n            throw new NotImplementedException(\"Private static field assignment\");\n        }\n\n        // Get an unsafe accessor for this field/property (this internally caches and adds it to the output list of unsafe accessors)\n\n        // [UnsafeAccessor(UnsafeAccessorKind.Field, Name = \"<Name>k__BackingField\")]\n        // static extern ref int UnsafeAccessor_Foo_Name(Foo f);\n        var unsafeAccessorDeclaration = GetUnsafeAccessorDeclaration(\n            memberExpression.Member is PropertyInfo propertyInfo\n                ? propertyInfo.SetMethod ?? throw new UnreachableException(\"Attempting to assign to property without setter\")\n                : memberExpression.Member,\n            forWrite: true);\n\n        // The unsafe accessor declaration has been created; invoke it.\n        Result = memberExpression.Member switch\n        {\n            FieldInfo => AssignmentExpression(\n                assignmentKind,\n                (ExpressionSyntax)_g.InvocationExpression(","sourceCodeStart":1690,"sourceCodeEnd":1726,"githubUrl":"https://github.com/dotnet/efcore/blob/3a2006ef569de08368d59db5e1468aa8f407e4f8/src/EFCore.Design/Query/Internal/LinqToCSharpSyntaxTranslator.cs#L1690-L1726","documentation":"Thrown by LinqToCSharpSyntaxTranslator.TranslateNonPublicMemberAssignment when assigning to a non-public member whose MemberExpression.Expression is null — i.e. assigning to a private/internal static field or property. The UnsafeAccessor translation path covers instance writes only; static private writes are unimplemented.","triggerScenarios":"An expression tree assigns to a private/internal static field or static property setter through a MemberExpression with a null target (Expression.Assign(Expression.Field(null, fieldInfo), value)).","commonSituations":"Code that mutates private static state (configuration flags, caches) via reflection-built expression trees; provider/test fixtures that wire internal statics through Expression.Assign.","solutions":["Expose a public static setter or a method that performs the assignment, and call that from the expression tree.","Move the mutable state to an instance so the static-write path is not needed.","If the static is effectively a constant after startup, inject it as a constant instead of writing to it."],"exampleFix":"// before — assigns to a private static field via reflection\nvar field = typeof(Config).GetField(\"s_value\",\n    BindingFlags.NonPublic | BindingFlags.Static)!;\nvar assign = Expression.Assign(\n    Expression.Field(null, field),\n    Expression.Constant(42));\n\n// after — expose a public static setter and call it\npublic static void SetValue(int v) => s_value = v;\nvar assign = Expression.Call(\n    typeof(Config), nameof(Config.SetValue), null,\n    Expression.Constant(42));","handlingStrategy":"validation","validationCode":"// Reject assignments to non-public static members.\nusing System.Linq.Expressions;\nusing System.Reflection;\n\nbool AssignsToPrivateStatic(Expression e)\n{\n    bool bad = false;\n    new AssignChecker(assign =>\n    {\n        if (assign.Left is MemberExpression { Expression: null, Member: var m })\n        {\n            var pub = m switch\n            {\n                FieldInfo f => f.IsPublic,\n                PropertyInfo p => p.SetMethod?.IsPublic ?? false,\n                _ => false,\n            };\n            if (!pub) bad = true;\n        }\n    }).Visit(e);\n    return bad;\n}\n\nclass AssignChecker(Action<BinaryExpression> onAssign) : ExpressionVisitor\n{\n    protected override Expression VisitBinary(BinaryExpression b)\n    { if (b.NodeType == ExpressionType.Assign) onAssign(b); return base.VisitBinary(b); }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Expose a public static setter or method for any state that must be mutated from expression trees.","Move mutable static state into an instance so static-write paths are not needed.","Pre-scan trees for static-target assignments before translation."],"tags":["ef-core","expression-trees","reflection","unsafe-accessor","static","assignment","code-generation"],"backgroundTag":null,"analyzedSha":"3a2006ef569de08368d59db5e1468aa8f407e4f8","analyzedAt":"2026-08-11T23:42:04.146Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}