-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Description
The other day I modified some non-null-safe code from:
class Foo {
int x;
Foo({int x = 42}) {
// Other work.
}
}to:
class Foo {
int x;
Foo({int x})
: x = x ?? 42 {
// Other work.
}
}It turns out that this was wrong because that "Other work" portion in the constructor body referenced x, and because the local x parameter understandably shadows the x member, it therefore was not using the expected default value. Oops. I didn't realize this mistake until I later attempted to migrate the code for null-safety.
This is probably less of a problem with null-safety enabled, although it could still happen. For example:
class Foo {
int x;
late String string;
Foo({int? x}) : x = x ?? 42 {
string = x.toString();
}
@override
String toString() => string;
}
void main() {
print(Foo()); // Want '42', but prints 'null'.
}Or it could just be something like:
class Foo {
int x;
Foo({int? x}) : x = x ?? 42 {
int updatedValue = someMemberFunction();
x = updatedValue;
}It would be nice if there were some lint that suggested using this.x instead of x in the constructor body for these situations. In the specific case of constructors, if a parameter name and a member name are the same, it seems rare to me that someone would prefer the parameter; I think it would almost always be a mistake. This isn't fully baked, but I think criteria would be something like:
- Class
Thas a member variablexand a constructor with a parameter namedx. That constructor has an initializer list that initializesxthat is notx = xorthis.x = x. (Intention is to lint only if the member and parameter potentially have different values.) - Class
Thas a setter namedxand a constructor with a parameter namedx. That constructor has a body that assigns tox.