Allan Juan
Allan Juan

Reputation: 2554

Why should I avoid wrapping fields in getters and setters?

I am building a Flutter app. I have a class that looks like this:

class ToDo {
    String _title;
    bool _done;

    String get title => _title;
    void set title(String newTitle) { _title = newTitle; }

    bool get _done => _done
    void set done(bool done) { _done = done; }
}

But the Dart linter is complaining that I should "Avoid wrapping fields in getters and setters just to be safe". However, this doesn't make much sense to me. Right now the getters are useless, but what if in the future I need to do some kind of processing before accessing a variable from outside? All I'll have to do is update the getters. However, if the properties were public and being accessed directly, I would have to update the whole codebase if some business rule changed.

So what is the point of this warning? Or, in other words, why creating "useless getters" would be a bad practice?

Upvotes: 20

Views: 11434

Answers (3)

Jeff Frazier
Jeff Frazier

Reputation: 579

This linter issue also goes away if you don't name the setter the same as the getter. And while it's valid, naming them the same feels wrong anyway and makes the code harder to understand.

String get id => _id;
void set setId(String id) => _id = id;

Upvotes: 0

Andrew Thompson
Andrew Thompson

Reputation: 139

Just to add to this I would like to make an additional comment. This error goes away if you do something else within the setter, not just set the value. In my use case I was setting a value in a Provider and was calling notifyListeners(). By adding this additional functionality the lint warning disappears. I guess because the setter is doing more than just setting the value.

Upvotes: 4

jamesdlin
jamesdlin

Reputation: 90005

However, if the properties were public and being accessed directly, I would have to update the whole codebase if some business rule changed.

Ask yourself this: what exactly would you need to change in your Dart codebase if you had to change a public member to use an explicit getter and setter instead?

In most languages, getters and setters look like method calls to consumers. If you wanted to replace a public data member with a public getter and setter, that would be a breaking API change, requiring changes to everything that uses it.

Dart is not like that. Getters and setters do not look like method calls to consumers; they are indistinguishable from direct member access. (Having a public data member implicitly declares a corresponding getter and setter as part of the class's interface.) Changing a public data member to a public getter and setter would not require any changes to callers, so providing trivial getters and setters around private member variables provides no benefit.

(This is also explained by the documentation for the unnecessary_getters_setters lint that you encountered.)

Incidentally, the unnecessary_getters_setters lint should occur only if you provide both a getter and a setter (which is not what your example code does). If you provide only one, then it would no longer be equivalent to a public data member.

Upvotes: 33

Related Questions