-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Description
If you want to initialize a private instance field from a named parameter, you currently have to write an explicit initializer like:
class House {
int? _bedrooms;
House({int? bedrooms}) : _bedrooms = bedrooms;
}
main() {
House(bedrooms: 3);
}With the upcoming "Private Named Parameters" feature, you can instead write:
class House {
int? _bedrooms;
House({this._bedrooms});
}
main() {
House(bedrooms: 3); // Still uses public name.
}Likewise with primary constructors:
class House({final int? _bedrooms});
main() {
House(bedrooms: 3); // Still uses public name.
}When private named parameters ship, I believe we should unconditionally encourage users to use a private named parameter when possible. To that effect, I think we should add a lint that recognizes the older explicit initializer pattern. Concretely, the lint should fire when all of:
- A constructor has a named parameter,
- that is used in the initializer list to initialize an instance field,
- whose name is the same as the parameter but with
_prepended, - and there are no uses of the parameter in the constructor body.
The lint should apply to both primary and non-primary (but generative) constructors.
The lint should not apply to instance fields that are initialized in the constructor body, like:
class House {
int? _bedrooms;
House({int? bedrooms}) {
_bedrooms = bedrooms;
}
}Turning that into a private named initializing formal could change the initialization order in ways that are visible or possibly change the behavior in other subtle ways if there is other code in the constructor body. To keep things simple, the lint only applies to fields initialized in the actual initializer list (which most are anyway).
See also the corresponding quick fix issue: #62240
cc @pq