Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
rarbatrol
Apr 17, 2011

Hurt//maim//kill.

Nude posted:


I always kind of wondered why C# allowed properties in general instead of just explicit getters and setters functions honestly.

E: fixed typo.

Having jumped between Java and C# for a few days in a row, I appreciate how much less typing I have to do with properties.

Edit: Also, if you can overload operators, just have the drat thing always return true.

Adbot
ADBOT LOVES YOU

Taffer
Oct 15, 2010


Nude posted:


I always kind of wondered why C# allowed properties in general instead of just explicit getters and setters functions honestly.

E: fixed typo.

Why? Genuine question. How is

code:
object.thing
different than

code:
object.getThing()
Especially considering that getThing() will most of the time just be

code:
fun getThing() {
    return thing
}
I realize "most" is an assumption but if it needs to be more than that you can overload a getter.

Eela6
May 25, 2007
Shredded Hen
Properties also have the advantage of letting you refactor an interface more easily. You can start with a publicly available property and then refactor it to setters/getters as your requirements change while breaking less code.

Jewel
May 2, 2009

Taffer posted:

Why? Genuine question.

Because accessing a variable and having it potentially do an expensive operation or cache something or increment or whatever it's doing is a scary thing when you have no idea that it might be doing that without checking every variable to see if it has a custom getter. At least functions give you an idea they have the possibility of doing something (and can even be named appropriately).

Eela6
May 25, 2007
Shredded Hen

Jewel posted:

Because accessing a variable and having it potentially do an expensive operation or cache something or increment or whatever it's doing is a scary thing when you have no idea that it might be doing that without checking every variable to see if it has a custom getter. At least functions give you an idea they have the possibility of doing something (and can even be named appropriately).

Hmm. I'm not sure if I agree, but that's a strong argument.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
It's because it's really weird to have two different syntaxes for accessing a property of an object, just based on whether or not it's a raw field. See also, why c# has indexers instead of making you write a get(int) method.

Also, setSomeLongPropertyName(getSomeLongPropertyName() + 1) is horrible garbage compared to just SomeLongPropertyName++ (or += 1).

KernelSlanders
May 27, 2013

Rogue operating systems on occasion spread lies and rumors about me.

Jewel posted:

Because accessing a variable and having it potentially do an expensive operation or cache something or increment or whatever it's doing is a scary thing when you have no idea that it might be doing that without checking every variable to see if it has a custom getter. At least functions give you an idea they have the possibility of doing something (and can even be named appropriately).

Except that in Java every public field is supposed to be accessed through getters or setters, so it just amounts to more typing, longer lines, and more boiler plate.

Eggnogium
Jun 1, 2010

Never give an inch! Hnnnghhhhhh!
C# properties are awesome. Yes, they can be abused by amateur or bad coders but so can everything else.

The Phlegmatist
Nov 24, 2003

KernelSlanders posted:

Except that in Java every public field is supposed to be accessed through getters or setters, so it just amounts to more typing, longer lines, and more boiler plate.

It doesn't have to be that way. It's just common convention among Java devs.

C++ devs are more likely to expose data members as public as long as changing them won't break an object's state. This has the side benefit of telling you that a setter method is probably doing some other stuff behind the scenes if it was implemented that way.

e: Java famously has AWT using public variables when it's not really a good idea to do so, and obviously could never change it after the fact once it got into client code. So there's precedent for encapsulating absolutely everything because you can't exactly go back on your decision to expose too much to the caller.

The Phlegmatist fucked around with this message at 05:07 on Jan 17, 2018

Taffer
Oct 15, 2010


Jabor posted:

It's because it's really weird to have two different syntaxes for accessing a property of an object, just based on whether or not it's a raw field.

That depends on the language. Swift and kotlin for example put extended getters and setters on the property itself, so everything is accessed the same way, even if some operation is required. It's cleaner, more concise, and has far less boilerplate.

The arguments posted don't really explain why a getter is better to me, but maybe that's because of the basis in languages that don't do property access that way. I'm planning to learn C# soon so I guess I'll learn that. But coming from Java, I really hate enforced getters and setters.

Nude
Nov 16, 2014

I have no idea what I'm doing.

Jewel posted:

Because accessing a variable and having it potentially do an expensive operation or cache something or increment or whatever it's doing is a scary thing when you have no idea that it might be doing that without checking every variable to see if it has a custom getter. At least functions give you an idea they have the possibility of doing something (and can even be named appropriately).

This is my main reason, although I admit in c# it's not like I'm going to go out of my way and not use the convenient option. But I don't think I'm gonna win many people over with csharp getter/setters muddles the difference between a variable and a method. As KernelSanders is right it's based off of Java's standard, so if you go off of that this is a logical step to take. I'm just baffled by how much you can make what looks like a regular variable, do pretty much anything under the hood (including cast it to another type and back and stuff like that). But to C#'s credit I've never seen this out in the wild so far when using other people's libraries, so admittedly it's weak argument.

I appreciate your responses either way, was genuinely curious on everyone's thoughts.

CPColin
Sep 9, 2003

Big ol' smile.
I like how all the OOP classes were like "encapsulate everything so you can change the underlying code and not break code that uses your class!" when 1) 90% of the member data in classes you're gonna write in life aren't gonna change, 2) 90% of the classes that do change are in your dumb code that you have total refactoring control over, and 3) who gives a poo poo when stuff is trending toward immutability by default now anyway.

I wonder how many of our "best" design practices are still rooted in not having an IDE and thinking our code is going to be used by anybody else ever.

Foxfire_
Nov 8, 2010

C# properties are nice for making noun-y things look noun-y.

Like if you have an Image class, Height, Width, NumPixels, BitDepth, NumBytes, and RowStride are all reasonable things to expose, and the implementation would probably have some of them be variables and some be calculated. Making them properties makes them all accessed the same and (in non-crap code) is strongly suggesting that accessing them is idempotent and inexpensive.

TheresaJayne
Jul 1, 2011

Doom Mathematic posted:

Well, I wasn't in the interview, we only have the candidate's paraphrase for it, but "They said nothing is impossible. It happened 2 weeks back" says to me that it happened.

But even if it was dreamt up as a thought experiment, the only way code like this can happen is if you disobey hard-earned years of best practice and deliberately shirk industry standard code quality tools. Nobody should ever need to know how == or with work anymore. These practices are, in large part, why programming in JavaScript is more tolerable now than it was in ages past. This says something about practices at this potential employer, about the kind of code they are responsible for, the level of nonsense that employees are going to have to put up with.

Maybe somebody wrote a non-deterministic getter somewhere along the line, and this is a simplification of that problem intended to highlight the issue. Getters have legitimate use cases and I guess they can go wrong in that way if they become too complex. Still doesn't explain the double-equals thing though.

One place i was working at , we actually gave candidates real issues to solve as part of their interview, So this may have been to find a candidate who knows how it can happen to make sure it can't again.

Rottbott
Jul 27, 2006
DMC
The possibility of a property doing something unpleasant when accessed seems no worse than the possibility of a getX() method doing something unpleasant. Especially in C# where there's no const.

Nth Doctor
Sep 7, 2010

Darkrai used Dream Eater!
It's super effective!


Rottbott posted:

The possibility of a property doing something unpleasant when accessed seems no worse than the possibility of a getX() method doing something unpleasant. Especially in C# where there's no const.

Is there a subtle difference between
const and static final that I'm not grokking?

Rottbott
Jul 27, 2006
DMC

Nth Doctor posted:

Is there a subtle difference between
const and static final that I'm not grokking?
final isn't a thing in C# is it? C# methods (i.e. GetX()) can't be made const which means there's no way to prevent them from mutating the object.

NihilCredo
Jun 6, 2011

iram omni possibili modo preme:
plus una illa te diffamabit, quam multæ virtutes commendabunt

Sometimes I write a method that will load or create an expensive value on the first invocation, then cache the result and return that for the object's lifetime.

I'm always unsure if that kind of lazy loader should be a (read only) property or a function. The former suggests that it's just accessing a field, but the latter conversely suggests that it's doing work every time, neither of which is correct. Currently I lean towards properties because the method is effectively idempotent.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
Yeah there is, you just write them to not modify any of the object's fields. It's not like method bodies are created by some mystical process outside your control.

Sure, if you want to communicate to callers of a method that a particular method doesn't modify the object, then sure, you only have conventions rather than anything actually enforced by the language. But that's true of a great many things in pretty much every language you care to name. For example, it's only convention that setX() and getX() are at all related in any way.

Nth Doctor
Sep 7, 2010

Darkrai used Dream Eater!
It's super effective!


Rottbott posted:

final isn't a thing in C# is it? C# methods (i.e. GetX()) can't be made const which means there's no way to prevent them from mutating the object.

final is a thing, on properties, at least.

SirViver
Oct 22, 2008

Nth Doctor posted:

final is a thing, on properties, at least.
No. The closest things C# has to Java's final are sealed and readonly. The first is a class modifier and makes it so you can't inherit from that class anymore, and the latter is a field (not property) modifier that ensures that field can only be written to in the field initializer/constructor. For auto-implemented properties the equivalent to readonly is only specifying { get; }, which makes it functionally the same as a readonly field.

Nth Doctor
Sep 7, 2010

Darkrai used Dream Eater!
It's super effective!


SirViver posted:

No. The closest things C# has to Java's final are sealed and readonly. The first is a class modifier and makes it so you can't inherit from that class anymore, and the latter is a field (not property) modifier that ensures that field can only be written to in the field initializer/constructor. For auto-implemented properties the equivalent to readonly is only specifying { get; }, which makes it functionally the same as a readonly field.

This will teach me to look at programming stuff before having coffee. const is in fact a thing in C#: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/const

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



canis minor posted:

Oh, you kind of can - for `+` (but that's not proper overloading, but rather casting (?)). I think operator overloading won't come soon to JS, if at all. Still people try to do it

Phew, I thought that meant it was accepted in ESnext - glad to hear it hasn't been

raminasi posted:

I'm pretty sure they're just syntactic sugar for getters and setters. I don't think that the CLR has any special use for them.

They are, but I figure a clever optimizer could do something around the fact that they're a guaranteed getter/setter rather than just another method that happens to begin with 'get' or 'set'. Maybe not, though, maybe it's 'just' a vastly more pleasant syntax.

Thermopyle
Jul 1, 2003

...the stupid are cocksure while the intelligent are full of doubt. —Bertrand Russell

Alex Martelli identifies the benefits of properties when it comes to Python here.

In Python properties are usually preferred to getters/setters.

In langauges like Java where getters/setters are expected, it's still unexpected for there to be much going on in the getter/setter other than returning/setting the value...you really don't want to be doing a lot in there.

This is just a convention.

Properties are the same dealio. You could of course kick off a lot of processing in a property, but the convention, just like with getters/setters is to not.

The Phlegmatist
Nov 24, 2003

Thermopyle posted:

In langauges like Java where getters/setters are expected, it's still unexpected for there to be much going on in the getter/setter other than returning/setting the value...you really don't want to be doing a lot in there.

java.util.Date IIRC has a getter in it that mutates the object's state. Which is something rather unexpected. It's been deprecated for 20 years and I still see it in production code every once in a while.

1337JiveTurkey
Feb 17, 2005

If getters and setters help enforce encapsulation, it’s because they make it just a tiny bit more tedious to show the rest of the world fields that they maybe don’t need access to. Maybe things would be fine with mostly immutable state that’s all set by the constructor through dependency injection, reading from a config file or something else that doesn’t expose to the code using it what precisely it needs to complete its designated task.

Rottbott
Jul 27, 2006
DMC

Nth Doctor posted:

This will teach me to look at programming stuff before having coffee. const is in fact a thing in C#: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/const
Yeah, but not for methods. So as someone mentioned above, it's just a convention that getX() doesn't mutate, just as it is for properties. Therefore properties are no more open to abuse from that point of view than methods are. So saying "but a bad programmer might make them mutate" is wrong.

raminasi
Jan 25, 2005

a last drink with no ice

Munkeymon posted:

They are, but I figure a clever optimizer could do something around the fact that they're a guaranteed getter/setter rather than just another method that happens to begin with 'get' or 'set'. Maybe not, though, maybe it's 'just' a vastly more pleasant syntax.

What do you mean by "a guaranteed getter/setter?"

Absurd Alhazred
Mar 27, 2010

by Athanatos
You want a coding horror? C++ has a const modifier suffix for methods, which tells all and sundry that nothing in the method body is going to change anything about the object...

Except that you can change members if you declare them with a mutable modifier prefix!

C++ code:
class Test
{
public:
	void canDoNothing() const
	{
		ActuallyModifiableSucker++;
	}
private:
	mutable int ActuallyModifiableSucker;
}
:shepface:

eth0.n
Jun 1, 2012
Not a horror at all. Static enforcement of design contracts is great, even if there are escape hatches.

Linear Zoetrope
Nov 28, 2011

A hero must cook
I mean, Rust has that too with a bit more gymnastics and checking. Rust has RefCell which is runtime-borrow checked, but the use case is meant to be for things like caching slow computations like

code:
class Blah 
{
public:
    Result someReallyBigComputation() const 
    {
        if( cache == null) {
            cache = this->actuallyCompute();
        }

        return cache;
     }
}
private:
    Result actuallyCompute() { ... }
    mutable Result cache;
}
That is, "side effects" that are invisible but beneficial to the user and don't meaningfully affect the program state.

Linear Zoetrope fucked around with this message at 04:47 on Jan 18, 2018

Absurd Alhazred
Mar 27, 2010

by Athanatos

Linear Zoetrope posted:

That is, "side effects" that are invisible but beneficial to the user and don't meaningfully affect the program state.

Oh, you mean like caching memory access during branch prediction?

The Phlegmatist
Nov 24, 2003

Absurd Alhazred posted:

You want a coding horror? C++ has a const modifier suffix for methods, which tells all and sundry that nothing in the method body is going to change anything about the object...

Except that you can change members if you declare them with a mutable modifier prefix!

If you start declaring data members as mutable I'm going to murder you after work in the parking lot.

That's how encapsulation is done in C++.

JawnV6
Jul 4, 2004

So hot ...

Absurd Alhazred posted:

Oh, you mean like caching memory access during branch prediction?

vOv
Feb 8, 2014

If you didn't have mutable then you couldn't have an internal mutex with const getters because you'd have no way to lock it.

vOv fucked around with this message at 07:02 on Jan 18, 2018

redleader
Aug 18, 2005

Engage according to operational parameters
For what it's worth, Microsoft have published some guidelines on when to use properties here and here. It's mostly sensible stuff, although I disagree with a couple of things (in particular DO allow properties to be set in any order even if this results in a temporary invalid state of the object). A lot of the recommendations are mostly language-independent, so have a look if your lang has properties.

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

redleader posted:

It's mostly sensible stuff, although I disagree with a couple of things (in particular DO allow properties to be set in any order even if this results in a temporary invalid state of the object).

Is that such a bad idea? Properties are meant to be pretty simple and act like fields right? So requiring changes to be made in some specific order would be confusing and a bit magical

If you had plain fields you'd have to do the combined state validation at showtime too, just sounds like they're recommending the same behaviour. If you need to police state changes as they happen, methods that take all the parameters (or data classes or builders) are probably the way to go I'd have thought?

redleader
Aug 18, 2005

Engage according to operational parameters

baka kaba posted:

Is that such a bad idea? Properties are meant to be pretty simple and act like fields right? So requiring changes to be made in some specific order would be confusing and a bit magical

If you had plain fields you'd have to do the combined state validation at showtime too, just sounds like they're recommending the same behaviour. If you need to police state changes as they happen, methods that take all the parameters (or data classes or builders) are probably the way to go I'd have thought?

Yeah, good point. I was thinking from the point of view that you should try to avoid objects from being in invalid states whereever possible. But you're right, the fact that properties are intended to look like and work like fields is probably a more important concern.

And if it's that important to keep an object in a valid state, you probably wouldn't expose the fields directly either :v:

NihilCredo
Jun 6, 2011

iram omni possibili modo preme:
plus una illa te diffamabit, quam multæ virtutes commendabunt

redleader posted:

Yeah, good point. I was thinking from the point of view that you should try to avoid objects from being in invalid states whereever possible. But you're right, the fact that properties are intended to look like and work like fields is probably a more important concern.

And if it's that important to keep an object in a valid state, you probably wouldn't expose the fields directly either :v:

Read-only properties exist for this. The getters can be brain-dead accessors, the setters need to go through validation.

code:
public uint Age { get; private set; }
public bool Alive { get; private set; }

public bool ChangeStatus(uint age, bool alive)
{
   if (alive && age > 130) { return false; }
   Age = age;
   Alive = alive;
   return true;
}

Adbot
ADBOT LOVES YOU

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



raminasi posted:

What do you mean by "a guaranteed getter/setter?"

That they're guaranteed to have a certain narrowly defined structure surrounding some user code where that structure is slightly more narrowly defined than the mostly-equivalent hand-rolled methods. Off the top of my head, you could write a setter like

C# code:
public void setX (T x = default(T)) {
   this.x = x;
}
But you can't have a property that compiles to that equivalent method signature because the parameter to a property setter can't be optional. My thought was that there might be optimizations the JIT could do given that guaranteed structure around property code, but maybe not, I dunno.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply