Ranter
Join devRant
Do all the things like
++ or -- rants, post your own rants, comment on others' rants and build your customized dev avatar
Sign Up
Pipeless API
From the creators of devRant, Pipeless lets you power real-time personalized recommendations and activity feeds using a simple API
Learn More
Comments
-
mojo20127834ySo just use getters/setters. But it would prevent the IDE from displaying it as property (icon in auto complete, property editors)
-
Plain getters and setters are a chore. You have to type them out or generate them, then maintain them when something changes. It's necessary because you may need to make the behavior more complex in the future while preserving backwards compatibility. That's not possible with direct field access, so you have to add getters and setters. Properties solve this problem: they're something that behaves like direct field access, but you can modify the behavior later - but you don't have to maintain any futureproofing boilerplate until that hypothetical future actually happens.
If you're communicating failures with return values, you're doing it wrong. An error should either be handled, ignored explicitly or bubble up the stack. Return values can be overlooked and surprise you later when your code misbehaves because you forgot to handle an error indicated by return value. Exceptions guarantee that errors are handled gracefully or prevent the code from progressing in case of error. -
@gronostaj
But why use the properties if theres a chance down the road it would need to be a method, and there's no advantage other than being pretty...
thats the thing i dont get, im aware that once we'r talking bindings thats where properties come in
but otherwise - again IMO - i merely see properties as pretty getter/setter methods, that can't notify the program/user of successfull or failed set action, unless you start throwing exceptions - which as ive read in the books and seen around that throwing exceptions from the setter of a property is generally frowned upon ?
Asked my teacher this and he couldn't answer me why i should then use properties over getter/setter methods unless we'r talking bindings, and he's a strong advocate of properties, but had to recognise that you could end up making a setter in a property that didnt actually set a value, and it wouldnt get notified unless exception thrown which he wouldnt do, or you check the field afterwards if it changed 😅 -
> there's no advantage other than being pretty
There is: no need to maintain boilerplate that 95% of time is a waste of time.
I've seen my share of problems caused by getters and setters not being properly renamed along with properties. Modern IDEs mostly solve this problem, but if a program can solve such problem without your interaction, then apparently the language design forces you to do work that could be carried out by the computer itself in the first place.
The need to write two methods just to add a single field is a language design failure. It makes changing the code in the future more cumbersome and adds additional points where potential bugs can be introduced.
Also, don't underestimate clarity. It doesn't matter much for toys and throwaway code, but actual production code is read much more often than written. It's crucial to be able to navigate and understand it efficiently. -
> i merely see properties as pretty getter/setter methods, that can't notify the program/user of successfull or failed set action, unless you start throwing exceptions - which as ive read in the books and seen around that throwing exceptions from the setter of a property is generally frowned upon ?
Getters and setters should be dead simple. Most of the time they should only mutate object's state and have no failure conditions, save for validation , ie. when the new state would be invalid. For example you can't have a shop order completed and cancelled simultaneously so attempt to set both of those true should fail - it means that either your program has a bug that leads to this invalid state or that user requested invalid state change and you have to react accordingly.
If your method has other reasons to fail than because its call is illegal, then it's not just a setter and should be modified to not look like one, because others can make incorrect assumptions about it. -
Finally, as I already said earlier, the proper way to signal errors is by throwing exceptions. They guarantee that a problem won't be silently ignored and make more mess down the road. Reporting errors via return values is very rarely the right solution. Especially with setters, which IMO should either return nothing or `this` (fluent setters). If you need to return something else from a setter, it may actually be a "regular" method disguised as a setter and should be dealt with.
-
@gronostaj, so, if understand you correct.. you'd say that once a setter does more than a 'this.age = age'
Or a getter 'return this.age' we should opt to do the validation/computation of the age in a seperate method that then use property setter once age validation is done ?
So if this was a person class.
We could have following:
Public void validateAge(int age)
{
If (age>5)
{
This.age = age
}
Else
{
//Handle if age to low
}
} -
@Ranchonyx microsoft java 🤔? Must be a programming joke i havent heard yet? 😅
-
@BitByteBoolean yes, Microsoft Java is C#, at least I see it as such for obvious reasons.
-
@Ranchonyx well from that viewpoint i definitly agree, i find it's picked up so quick, and alot are just like java ☕
-
I'm saying that if, for example, you have a method like this:
public void setAmountInEuros(int amountInEuros) {
this.amountInDollars = this.convertEurosToDollars(amountInEuros);
}
Then it's a fake setter - it doesn't just set an underlying value and it can fail eg. because currency conversion requires rate of exchange which is unavailable temporarily. This method should be renamed to not look like a setter or maybe moved to a dedicated service. Otherwise one could incorrectly assume that it's just a setter and there are no error conditions.
(continued...) -
Validation is a special case IMO, because you can take the "always valid entity" approach which has its benefits (and drawbacks also, but that's a story for another day). It's an approach where the data structure-like object (used for data storage only, basically just getters and setters) is validating all its changes itself and illegal operations are assumed to be programming errors. With this approach the caller of setters should make sure by itself that it's making a legal and illegal calls should never happen, but if they do, you want to know about that and throwing an exception from the setter (or constructor) is the right thing to do.
(continued...) -
And just to make this complete, there are valid cases when a setter is something different than just `this.foo = foo;`, that's why we're using setters actually. Let's say we have a User class. The user is initially deactivated and they have to activate their account.
public class User {
private boolean activated = false;
public boolean isActivated() {
return this.activated;
}
public void setActivated(boolean activated) {
this.activated = activated;
}
}
(continued...) -
Now you want to add an ability to disable an account of misbehaving user. You could do this:
public class User {
private UserStatus status = UserStatus.DEACTIVATED;
public UserStatus getStatus() {
return this.status;
}
public void setStatus(UserStatus status) {
this.status = status;
}
}
But it would break all existing code that uses isActivated/setActivated methods (when you're developing a library or a huge system it's important to maintain backwards compatibility). So you could change `isActivated` to look like this:
@Deprecated
public boolean isActivated() {
return this.status.equals(UserStatus.ACTIVATED);
}
It's not a straightforward getter anymore, but there are no error conditions and old code using this method still works fine. The IDE will highlight usages of a deprecated method and you can slowly migrate to getStatus as you go. -
@gronostaj i dont think we'r quite on the same page, im well aware of how the getter/setter methods work, my issue is coming to C# from Java and understanding why everyone want's to use properties...
This is the showdown im concluding after my research on general guidelines and best practices :
Properties vs getter setter methods:
1 binding. 0
1 Setting 1
1 getting 1
0 inform/act on fail-success 1
0 computations 1
0 error on invalid set. 1
Im aware properties can do informs and stuff by throwing exceptions, but ive found most people frown upon throwing exceptions from properties(then it should be a method)
(Continued) -
My question is then just - why properties over getter/setter methods when the only thing you gain is binding and pretty code?
Ofc. I cant get around using properties when binding, but else...
The action would be the same wether i set in a method or property, but in the method i can inform myself of the operation and wont get silent failure like the set age example, and maintaining a getter/setter method is IMO same work as a property, they'd have the same lines of code inside the {} either way..
I seriously asked all my teachers about this, and none of them could argue for the use of properties, once its set up like that, other than saying thats what people do, and it looks better 🤔 which IMO isnt a good enough answer... So sorry if i am pushing you here mate, but im just trying to understand why everyone, every video, tutorial and teachers says that i should be using the properties outside binding 😅 -
I think I've already answered all of your questions ;)
> 0 inform/act on fail-success 1
> 0 computations 1
> 0 error on invalid set. 1
If you need to signal success or failure or perform computations, then you're dealing with fake setters. These should be renamed to not look like setters or extracted to a service. Neither a setter nor a property is a valid solution.
> why properties over getter/setter methods when the only thing you gain is binding and pretty code?
Less boilerplate, thus less maintenance burden. Boilerplate = extra places to introduce bugs. And pretty code _is_ important. -
@gronostaj i think im starting to get what you'r meaning :)
So. Let's say in class Person{}
Rather have a method checkAge() that the property can use in its setter (thereby passing responsibility to check the age to a method that can act upon issues) and then the setter can set age if it's returned valid ?
I think putting things like a checkAge() method in other places than the class would just be low cohesion and higher coupling?
The thing about maintenance/ boiler plate i dont really get 😄?
As i understand it, boilerplate is when the same code is written in more areas/classes, and the get/set method is written exactly the amount of times in a class that a property is, also, maintining the get/set in a method or a property should result in the same amount of maintenence work inside the {} as the functionality should be the same either way it was written? 😄 -
With C# properties you just use { get; set; } most of the time, you don't write explicit property getter and setter. You can upgrade from the short notation to the explicit one later if needed.
So instead of this:
public class Foo {
private int foo;
public int getFoo() {
return this.foo;
}
public void setFoo(int foo) {
this.foo = foo;
}
}
You get this:
public class Foo {
public int foo { get; set; }
}
Much less code, no extra names, type is used only once rather than three times. And assignments actually look like assignments and method calls are always method calls, not assignments wrapped with a setter.
Plus some languages don't require you to write anything extra at all. For example in Kotlin fields are always properties with a hidden backing private field. In Python a regular field can be promoted to a property anytime. -
@gronostaj
While i do see how it shortens down code, it still do not address the issues im concerned about, validation on setting 🤔
autoproperties cant have validation, else it should be manual property and then the code isnt that much shorter than a getter/setter method,i just want to be consistent about what and when i use either.
and as the only argument is prettyer code, and not perfomance gains/less maintainence (as maintainence of either type of setter/getter is the same within the {} after they are implemented)
I dont see the benefits outside of bindings.. else i see benefits in implementing the get/set methods due to validations, non silent failures and futureproofed usage...
The only reason i could see properties do the same, would be if we take the validation into a method called validateFoo()
{
//Validation code here
}
And then used the set of property after validated input.
Or if we used property with throwing exceptions, which generally people dont want ? 😅 -
@BitByteBoolean As I said earlier, if you want to validate input data, throwing exceptions would be the preferred method. Failures should be signaled by exceptions so you can't miss them. An overlooked error that didn't stop the program can wreak havoc. (Alternatives to exceptions, ie. returning errors or signaling it through output arguments are prone to this problem.)
Even if you have to explicitly write setter's body, you still don't have to name the setter which already reduces the maintenance cost in case of renames.
Extracting validation to a method is an option, but that's a matter of style I guess? I haven't used a language that has properties for a while now. -
@gronostaj alright, i think ive gotten to the conclusion about when you use the properties of C# thanks for the chat my guy, always nice to reflect with someone about solutions and best practices.
After this discussing i might be inclined to use properties, and when necessary throw exceptions -> ill have a talk with my teachers about this again mext week and challange them with this discussion :)
Thanks for the help and chat !
Related Rants
Learning C# coming from Java...
What's the fuss about properties? As i see it, theyre only usefull for binding, as else they just work as syntetic sugar instead of getter/setter methods.
But properties are also limited to give response back, like a successfull set, unless you start throwing exceptions..
And if a set property has if(age>5){this.age=age} then if i pass the property a 4, you will never know as a user that it failed (again, unless you start throwing exceptions)
Im kinda feeling like i want to use get/set methods until i need to bind, then of course use property ?? Am i all off here?
question
help
properties
method
best practice
c#
learning