Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Nov 19, 2025

The IDE0032 code fixer incorrectly produced invalid code when a static field was assigned in an instance constructor, resulting in CS0200 (cannot assign to read-only property).

// Before: Valid code
private static Test? s_instance;
public static Test Instance => s_instance!;

public Test() { s_instance = this; }  // Instance ctor writes static field

// After applying old fix: Compiler error CS0200
public static Test Instance => field!;

public Test() { Instance = this; }  // Cannot assign to static read-only property

Changes

Code fixer logic (AbstractUseAutoPropertyCodeFixProvider.cs)

  • Modified constructor filtering to match static-ness of the field
  • For static fields, only static constructors are considered valid initialization contexts
  • For instance fields, only instance constructors are considered valid initialization contexts
  • Instance constructor writes to static fields are now treated as "outside constructor", causing a private setter to be added

Result
The code fixer now generates valid code with a private setter:

public static Test Instance { get; private set; }

public Test()
{
    Instance = this;  // Valid - property has a setter
}

Tests

Original prompt

This section details on the original issue you should resolve

<issue_title>IDE0032 code fixer produces invalid code for static field assigned in constructor</issue_title>
<issue_description>Version Used:
Visual Studio 2026 v18.0.0
.NET 10

Steps to Reproduce:

  1. Use the following minimal code sample:

    public sealed class Test
    {
        private static Test? s_instance;
        public static Test Instance => s_instance!;
    
        public Test()
        {
            s_instance = this;
        }
    }
  2. Observe that the analyzer reports IDE0032 for s_instance.

  3. Apply the code fix suggested by the IDE.

  4. Observe that the produced code cannot be compiled.

Diagnostic Id:
IDE0032: Use auto-implemented property

Expected Behavior:
The code fixer should not create invalid code that will not compile.

Actual Behavior:

The code fixer rewrites the class to:

public sealed class Test
{
    public static Test Instance => field!;

    public Test()
    {
        Instance = this;
    }
}

This results in the following compiler error:

CS0200: Property or indexer 'Test.Instance' cannot be assigned to — it is read only
```</issue_description>

## Comments on the Issue (you are @copilot in this section)

<comments>
</comments>


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

@CyrusNajmabadi
Copy link
Member

@copilot the analyzer/fixer checks if there are writes to the field to determine if it should make a private setter. However it ignores writes inside of constructors (as a private setter isn't needed for an instance property in that case).

However, as this is a static property we should not ignore instance constructor writes.

…tance constructors

- Added check to prevent diagnostic when static property has no setter and field is written in instance constructor
- Added IsStaticConstructor abstract method to distinguish instance vs static constructors
- Implemented IsStaticConstructor for both C# and VB analyzers
- Added test cases to validate the fix

Co-authored-by: CyrusNajmabadi <4564579+CyrusNajmabadi@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix IDE0032 code fixer to produce valid code Fix IDE0032: Prevent suggesting auto-property when static field written in instance constructor Nov 19, 2025
Copilot AI requested a review from CyrusNajmabadi November 19, 2025 06:01
Copilot finished work on behalf of CyrusNajmabadi November 19, 2025 06:01
…nce constructor writes

- Modified AbstractUseAutoPropertyCodeFixProvider to filter constructors based on static-ness
- For static fields, only static constructors are considered valid initialization contexts
- For instance fields, only instance constructors are considered valid initialization contexts
- Writes in mismatched constructors (e.g., instance constructor writing static field) are now treated as writes outside constructor, causing a setter to be added
- Updated test to expect a private setter to be generated instead of no diagnostic

Co-authored-by: CyrusNajmabadi <4564579+CyrusNajmabadi@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Nov 19, 2025

@copilot the analyzer/fixer checks if there are writes to the field to determine if it should make a private setter. However it ignores writes inside of constructors (as a private setter isn't needed ...

Fixed in dafbf3f. The code fixer now filters constructors by static-ness - for static fields, only static constructors are included when determining if writes are "outside constructor". Instance constructor writes to static fields now correctly trigger a private setter to be added.

Copilot AI changed the title Fix IDE0032: Prevent suggesting auto-property when static field written in instance constructor Fix IDE0032: Code fixer adds setter for static properties with instance constructor writes Nov 19, 2025
Copilot finished work on behalf of CyrusNajmabadi November 19, 2025 06:12
@CyrusNajmabadi CyrusNajmabadi marked this pull request as ready for review November 19, 2025 07:57
@CyrusNajmabadi CyrusNajmabadi requested a review from a team as a code owner November 19, 2025 07:58
@CyrusNajmabadi CyrusNajmabadi merged commit f6824bc into main Nov 19, 2025
26 checks passed
@CyrusNajmabadi CyrusNajmabadi deleted the copilot/fix-ide0032-code-fixer-issue branch November 19, 2025 18:16
@dotnet-policy-service dotnet-policy-service bot added this to the Next milestone Nov 19, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

IDE0032 code fixer produces invalid code for static field assigned in constructor

3 participants