Proposal: Reduce get-only property's accessor body ceremony (TypeScript-fashioned) #9306
Unanswered
Rekkonnect
asked this question in
Language Ideas
Replies: 3 comments 14 replies
-
public IReadOnlyList<Statement> ReplacedOrOriginal { get {
if (IsNoOp)
{
return [Original];
}
return Replacements;
}} |
Beta Was this translation helpful? Give feedback.
4 replies
-
Just to ask the obvious, what is wrong with the natural approach? public SolidColorBrush Brush => {
if (Dispatcher.UIThread.CheckAccess())
{
_brush.Color = Color;
}
return _brush;
} |
Beta Was this translation helpful? Give feedback.
7 replies
-
This addresses something that has bothered me for a while, too. Often with multi-statement lazy init. It's not the indentation and braces per se that I dislike, but rather the fact that the Syntax bikeshed: public SolidColorBrush Brush.get
{
// ...
}
public object this[string key].get
{
// ...
} |
Beta Was this translation helpful? Give feedback.
3 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Summary
Make the single accessor body of a property or indexer simplier to write without introducing ambiguity.
Motivation
Sometimes get-only properties or indexers need more than one line, so they can't be declared as expression-bodied (using
=>
). While they are designed to be properties as per the guidelines (trivial computation, no side-effects), it's simpler to use a method in their place, to avoid the extra nesting level introduced by theget
accessor.Consider the following real-world example:
The case here is the Brush property, which is a get-only property and could be declared as a method to avoid nesting the code one level deeper. We cannot use the ternary operator here, so this property will always be unnecessarily wrapped in one more set of braces.
Design
TypeScript has property bodies, which are methods declared by prepending a
get
orset
in front of them, like so:This syntax can be inspired from by placing the accessor keyword in the signature. While TypeScript requires the parentheses despite never allowing arguments, it's only because they have to be declared as functions. In C# we have no such requirement, so we can safely omit that.
So an approach can be the following:
We place the
get
keyword in between the property's type and its name. This is not valid code right now, so it can be used.The same approach can be followed to support explicitly implemented interface properties:
This can also extend to indexers, which might also be get-only, placing the
get
keyword between the return type and thethis
keyword, like so:Edges
The accessor's accessibility is always the property's accessibility, and can never be explicitly specified when the property only has one accessor, so nothing needs to be done in that area.
A non-partial property may only be declared in one of the two ways; with the traditional block-bodied accessor, or with the new syntax. The new syntax also supports the
abstract
,virtual
,override
,new
andpartial
modifiers.Partial properties may have their declaration part in either syntax and be implemented using the other, which won't be elaborated in this proposal.
Attributes on the property with no explicit target resolve to the property itself. The
method
andreturn
targets are valid to use in the new syntax, resolving to the property's accessor and not the property itself.Notes
Setters are not touched here. There might only be one case where using a setter-only property with a body makes sense over a method, and that is the indexer. An unrealistic example is below:
The above code could be then simplified to:
The proposal can be very easily extended to support setter-only properties, but it's intentionally left out of scope due to the high risk of enabling this declaration pattern.
Beta Was this translation helpful? Give feedback.
All reactions