Open feinstein opened 5 years ago
To be fair, the length difference between C#'s notation and Dart's current notation is almost indistinguishible here.
public string Example { get; private set; }
int _count = 5; int get count => _count;
Even then, the proposed notation is not that glanceable
List<int> counting = [];
int get _set count = 5;
final int counted = 21;
This easily gets lost in the sea of code, that might probably confuse newcomers quite easily.
Dart uses names to distinguish private and public members, and nowhere does it change a source identifier from one to the other. This syntax would introduce a field and a setter named _count
, which is a name that doesn't occur in the source.
Not saying it can't be done, or that I haven't wished for it often myself, but it's a subtle rewrite of the source code which may be lost on readers.
Maybe we could use some other syntax. Say:
int _x { get x; }
This introduces a field named _x
along with an extra implicit getter named x
.
You could do int _shared {get foo; get bar; set bar; }
and have extra implicit setters and getters for the field of any names. (There's still be a _shared
getter, and setter because the field is not final).
This does conflict with suggested syntax for declaring abstract getters and setters: int foo {get; set;}
, which would declare abstract an foo
getter and setter, and int foo{get => _foo, set(value) { _foo = value; }}
which would declare a concrete foo
getter and setter.
I think this syntax further complicates things and the problem of having a _x
that's not declared in code is not the end of the world. People don't use _
with variable names that already exist, and if they do, the compiler could just raise a warning, or raise it if they declare the variable again themselves.
C# creates the auto properties by using backing fields that can be accessed in code, its not recommended that you try to use them, but they are there and I have never seen anyone having a problem with it.
(sorry, I accidentally tapped the "comment and close button" while commenting on my phone).
As for @miyoyo comment on length, I think some syntaxes require more "mindful context-switch", where we shift our focus a bit, and it can be annoying. Like "ok now I create this variable as a getter, oh and I have to create this private-backing filed here, ok now I go back to what I was doing".
Although mathematically the declarations might be very close, psychologically they are not and this small context-switch is just annoying.
"ok now I create this variable as a getter, oh and I have to create this private-backing filed here, ok now I go back to what I was doing".
There's a lint for that: https://dart-lang.github.io/linter/lints/unnecessary_getters_setters.html
That lint is just for the case where there's an unnecessary getter or setter, but in my example I am specifying a necessary private setter and a necessary public getter.
necessary private setter
I think I see: in C#, a "private setter" provides write access to the implicit backing field. It's equivalent to an explicit backing field?
Precisely.
C# has auto properties which make creating public getters and private setters really easy, like
public string Example { get; private set; }
I would like to suggest that we have something similar in Dart, like this:
This code would be equivalent to what we have to do now: