Conversation started Dec 7, 2016 at 12:35.
jrh
jrh
Dec 7, 2016 12:35
@RobertHarvey part of the problem is that I may not have ran into a case where a property has really helped over a field, but I've ran into plenty of cases like this where properties leaked implementation details like this. Though again for non-final classes I definitely agree that the ability to override a property is great, for final classes properties feel like they violate YAGNI at best.
Another thing that comes to mind is a certain class representing a connection implemented an IsConnected property that seemed to imply that the socket was still there but in reality it was only set on an initial connection and was never reset when the socket was disposed.
While these are probably unambiguously bad designs if the guidance for properties wasn't so overwhelming, this bad code would have been easier to find, I have a hard time just trusting the semantic contract an object after this.
also for final classes properties feel like they violate YAGNI at best. I meant for properties that are just plain get/set.
 
1 hour later…
Dec 7, 2016 14:06
@jrh That post says, "Don't call private methods or fields using Reflection; expose a public method or property instead." Yes, reflection can expose implementation details if you use it, but that's not the fault of properties.
@jrh That's just a badly-designed class.
@jrh Think of it this way: you routinely lock the doors and windows to your house, for security reasons. Someone who is really determined could still break into your house. But that doesn't mean you simply give up and leave your doors and windows unlocked.
jrh
jrh
@RobertHarvey I was more referring to the Encapsulation section in the bottom half of my answer
i.e., The PlayerSocket getter allows other classes to run functions to modify the socket.... Note that PlayerSocket is a public property.
I agree that any calling code that depends on reflection as an "interface" isn't good.
Dec 7, 2016 14:22
It sounds like you believe that properties should not call other methods, even private ones.
jrh
jrh
I'm generally OK with properties calling static methods just for the sake of formatting strings, etc.
But in general, I feel like properties that modify or return the state of an object gets into murky territory, and is vulnerable to feature creep.
Isn't that kinda the whole purpose of properties?
@jrh That isn't the fault of properties, that's just a lack of encapsulation. In particular, this is what the Law of Demeter is about: by returning a Socket, the complete Socket interface has become part of the PlayerConnection interface.
jrh
jrh
Well... as I mentioned getting state gets murky for more complex objects (is it a copy, or THE thing), I rarely set state in objects, it's usually more configuration settings, not really "state".
Dec 7, 2016 14:29
Configuration settings are state.
Instead of returning the entire socket, that guy could have just exposed some useful property on the socket object, using a get-only property in his own class.
That's how you use a Property properly.
jrh
jrh
right, as I mentioned in my answer, but it gets tricky when the object itself is desirable, like Image in ImageList or PictureBox
Here's a better example: a class that contains a collection, like a dictionary. You can expose the collection as a public property, but you can also write an indexer instead. That indexer could do things like, for example, see if a key is already present in a dictionary before adding it. In an ordinary dictionary, that would be two steps, so now you have a dictionary that's a little bit smarter.
But at the end of the day, if you need to expose an ImageList or PictureBox as a property, then that's what you do.
jrh
jrh
Indexers are great, I think the IEnumerable interface definitely has its uses; though regarding ImageList and PictureBox, I'm not exposing the Controls, I'm talking about situations similar to the Image property ON those controls when I design classes with similar resource requirements.
@jrh If the object you're exposing has “unsafe” methods that you don't want to expose, the usual solution is to create an interface for the safe methods, then use the object adapter pattern to connect the interface to the actual object.
jrh
jrh
There's several cases where an Image property's ambiguity (copy or return the actual image?) on a class could have made the code very hard to read, I'd almost need both a GetCopy and GetImage method.
Dec 7, 2016 14:38
C# returns object references by value. It's almost always the actual object, not a copy. If you want copy semantics, you have to specify that explicitly.
What is "GetImage?" If you're coming from the Java world, that's not how it works in C#. It's simply Image.
jrh
jrh
hmm. The convention of C# returning object references instead of copies is important, I didn't think of it that way.
I agree, for reference types the assumption is never that I own that instance and are responsible for cleanup, unless I've created the instance or asked for a new copy.
jrh
jrh
In that case I suppose making my own Clone on a hypothetical (custom) Image class would have solved the problem
I was confused that ImageList violated the return a reference convention but if that's indeed an outlier than this might be a non-issue
 
Conversation ended Dec 7, 2016 at 14:41.