Reputation: 31
Recently started working in C# and I am making full use of the shorthand properties (Getters-Setters) and have a question about how to constrain the setter
I have a height property as follows
public int height {get; set;} = 200
The width property however has a minimum of 10px and is thus written in the original form
private int width = 100
public int Width
{
get
{
return this.width;
}
set
{
this.width = value > 10 ? value : 10;
}
}
My question is... Is there any way to keep the shorthand styled property yet manipulate it to have my ternary operator? Nearly all the other properties have the shorthand syntax and I like being consistent. (I know this is wrong but is something along the lines of this possible?)
public int width {get; set => value > 10 ? value : 10;} = 100
Upvotes: 1
Views: 6362
Reputation: 10573
No, you cannot have an auto-implemented getter and a custom setter (or vice-versa).
When you write:
T Prop { get; set; }
the compiler generates a special backing field for the property with a name that is inaccessible from actual C# code (disassembling .NET Core 3.1 compilation of the above code yields a name of <Prop>k__BackingField
) and creates a straightforward getter that returns its value and a setter that assigns value
to it.
Now, if either your set
or your get
is custom, there is no universal way of auto-generating a sensible counterpart. In your case the backing field width
is of the same type as the property itself and has the same name, only in lowercase. But one could easily have a backing field that has a different type and a different naming convention. Or the property could be a complicated combination of many different fields.
As you can see, this breaks down pretty easily, so the only feasible way an auto-generated counterpart could be implemented is "if there is a field with the same name as the property but lowercase (or lowercase preceded by an underscore, as is the standard .NET naming convention) then auto-generate the counterpart using that field". That's very specific and the complexity of implementing it does not warrant its usability, since the difference between:
T _prop;
T Prop
{
get => _prop;
set
{
... // custom code
}
}
and
T _prop;
T Prop
{
get;
set
{
... // custom code
}
}
is negligible. I'd even argue that the first one is more readable, since it specifically shows me the field being used and I don't have to look for it.
Upvotes: 2
Reputation: 4135
This is the closest you can come given C#'s language design:
private int width = 100;
public int Width
{
get => width;
set => width = value > 10 ? value : 10;
}
I'd recommend adding line breaks to the code to make it more readable and easy to debug; it's easier to add breakpoints to a new line than to a section of a single one.
Upvotes: 4
Reputation: 67380
Not as such, but you can definitely shorten the 12 line monstrosity above:
int width = 100;
public int Width { get => width; set => width = Math.Max(10, value); }
Upvotes: 1