Add code fix to suggest adding an error identifier as a parameter to the primary constructor
#76,738 opened on Jan 14, 2025
Repository metrics
- Stars
- (20,414 stars)
- PR merge metrics
- (Avg merge 6d 17h) (256 merged PRs in 30d)
Description
Summary
On identifiers that could not be bound to a symbol, used in property or field initializers of a type, offer a code fix to add a parameter with the given identifier in the type's primary constructor (if it has one).
Background and Motivation
A useful code fix that offers a workflow of declaring a list of fields and properties first and then adding their intialized values in the primary constructor.
Proposed Feature
Primary constructor parameters can be used within the initializers of members, so the code fix will be offered in that context. If the identifier has an error and is not bound to any symbol, offer the code fix, inferring the parameter's type and inserting the parameter to the type's constructor. Optionally, offer the code fix even for types that have not declared a primary constructor, but only if they have no non-primary constructors declared.
It would also be useful for the code fix to be offered with a batch fixer, adding all unbound identifiers in the scope as parameters with their inferred type to their respective types' primary constructors.
Examples
Basic
public sealed class ComposingService(string key)
{
private readonly string _key = key;
private readonly SomeService _service = service;
private readonly OtherService _otherService = otherService;
}
Triggering the suggestions on the identifiers service and otherService should show a code fix like "Add primary constructor parameter 'service'". Additionally, the batch fix on the entire document would add both service and otherService parameters on the primary constructor.
The single code fix on service will result in:
public sealed class ComposingService(string key, SomeService service)
{
private readonly string _key = key;
private readonly SomeService _service = service;
private readonly OtherService _otherService = otherService;
}
Without primary constructor
public sealed class ComposingServiceA
{
private readonly SomeService _service = service;
}
public sealed class ComposingServiceB
{
private readonly string _key;
private readonly SomeService _service = service;
public ComposingServiceB(string key)
{
_key = key;
}
}
The code fix may be offered for service in ComposingServiceA, since it has no declared constructors at all. But the code fix may not be offered for service in ComposingServiceB, because it already has a constructor declared, but not a primary constructor.
Across multiple types
public sealed class ComposingServiceA
{
private readonly SomeService _service = service;
private readonly OtherService _otherService = otherService;
}
public sealed class ComposingServiceB
{
private readonly SomeService _service = service;
}
The batch code fix will result in the following code:
public sealed class ComposingServiceA(SomeService service, OtherService otherService)
{
private readonly SomeService _service = service;
private readonly OtherService _otherService = otherService;
}
public sealed class ComposingServiceB(SomeService service)
{
private readonly SomeService _service = service;
}
Alternative Designs
None.