dotnet / dotnet/roslyn

Consider making IDE0044 (Make field readonly) precondition more strict/accurate

Open
#85,223 3 comments 0 reactions 0 assignees View on GitHub
Area-IDE Feature Request
Dominant language
C#
Stars
20.7k
Forks
4.3k
PR merge metrics
PR metrics pending

Description

**Brief description:**

Currently, IDE0044 is emitted whenever there's no assignment to a field outside of the constructor. However, adding `readonly` can alter semantics as methods might mutate a `struct`.

**Languages applicable:** Applicable to C# and VB.

**Code example that the analyzer should report:**

```csharp
public interface IFoo { void Init(); void DoWork(); }

public class C where T : struct, IFoo
{
// IDE0044: Make field readonly
// Prior to this issue: IDE0044 is reported.
// Suggestion: Do not report IDE0044 here.
private T foo;

// Two initialization modes available.
public C() { foo.Init(); }
public C(T f) { foo = f; }

public void DoTwice()
{
foo.DoWork();
foo.DoWork();
}
}
```

A real-world scenario is when `T` above represents a hash function that's resampleable, and `Init` samples one from the family.

**Additional information:**

The condition of reporting IDE0044 roughly has some similarities with that of simplifying identity conversions. (See #85201 ) I propose the following condition to be used for non-byref fields.

- If the field is assigned to outside of the constructors, **do not report** IDE0044 (this rule already exists). Otherwise, consider the rules below until a decision is first made.
- If the field is of reference type (a type-parameter type constrained to `class` or `class?` or a base class that's not `Enum`, or a reference type constructed from 0 or more type parameters), then IDE0044 **should be reported**.
- If the field is of value type that is known to be `readonly` (in this case, it must be a value type constructed from 0 or more type parameters that is not itself a type parameter), then IDE0044 **should be reported**.
- If the field type is pointer, then IDE0044 **should be reported**.
- Otherwise, **do not report** IDE0044.

Moreover, currently IDE0044 is not reported for byref fields. The proposed rule for byref fields is as follows.

- If the field is ref-assigned-to outside of the constructors, **do not report** IDE0044.
- Otherwise, IDE0044 **should be reported**.

**Documentation requirements:**

When this analyzer is implemented, it must be documented by following the steps at [Documentation for IDE CodeStyle analyzers](https://github.com/dotnet/roslyn/blob/main/docs/contributing/Documentation%20for%20IDE%20CodeStyle%20analyzers.md).

CC @jnm2

Contributor guide

Open the contributing guide

Research direction

Start with the IDE0044 analyzer and compare its existing precondition with the identity-conversion discussion in #85201. Verify the proposed behavior for the C# examples, including struct, reference, pointer, and byref fields, plus constructor-assignment cases, for both C# and VB. Complete the Documentation for IDE CodeStyle analyzers steps when the diagnostic behavior is updated.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
devtools
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.