Why is it "methods against properties"? A method does something. A property is, well, a member of an object. They're totally different things, although two kinds of methods commonly written - getters and setters - correspond to properties. Since comparing properties with methods in general is not meaningful, I'll assume you meant to talk about getters/setters.
Getter and setter method pairs are a code smell.
Not necessarily, I'd argue, but either way this isn't a matter of getters/setters vs. properties but a matter of whether either should be used. Also note that you can e.g. leave out the setX
part just like you can make read-only properties.
What is important to a consumer of an object is what it does, not how it does it. Its behavior is what it does; its state is how it does it. If you find yourself caring about an object's state (except for persistence, though this also breaks OO), you're simply not doing OOP and losing out on its advantages.
A highly questionable attitude. If the GUI wants to output data held by a DataStuffManagerImpl
, it needs to get that number from it somehow (and no, cramming half of the application into the widget class is not an option).
As the property gets more and more complex, the performance indication of using a property seems less and less truthful.
[Methods have] No performance guarantees. The API will remain truthful even if the method gets more complex. The consumer will need to profile their code if they are running in to performance issues, and not rely on word-of-API.
In almost all cases, all the validation logic etc. is still effectively O(1), or otherwise negible in cost. If not, perhaps you've gone too far and it's time for a change. And a getX()
method is usually treated as cheap as well!
Sure, typing myObject.Length is easier than typing myObject.Length(), but couldn't that be fixed with a little syntactic sugar?
Properties are that syntactic sugar.
Less for the consumer to think about. Does this property have a setter? A method sure doesn't.
"Is there a setter for this getter?" Same difference.
The programmer of the API will think more deeply about methods with return values, and avoid modifying the object's state in such methods, if possible. Separation of commands from queries should be enforced wherever possible.
I'm not sure what you're trying to tell us here. For properties, there's an even stronger unwritten law not to cause side effects.
In "Effective Java" item 43 p. 201, Joshua Bloch says, "There is no reason ever to return null
from an array- or collection-valued method." He recommends returning a zero-length array or an empty collection (Collections.emptyXxx) when there are legitimately no results. For one thing, it's a pain for the client to double-check everything:
if ( (retVal == null) || (retVal.size() < 1) ) {
...
}
Before returning null, ask yourself if the null return value is a result of a programming error on the part of the calling code. Such a check is generally done in the first few lines of a procedure as a defensive check for invalid input values and could legitimately result in throwing an unchecked exception instead of returning null. For my reasoning on this, please see the Checked vs. Unchecked Exceptions entry in my blog.
Scala and Haskell avoid returning null with an Option class. I don't immediately see how this is better than null (other than being type-safe just for the sake of it), but I thought I should mention it as another point of view:
val nameMaybe = request getParameter "name"
nameMaybe match {
case Some(name) =>
println(name.trim.toUppercase)
case None =>
println("No name value")
}
Bloch suggests that null is an appropriate return instead of an empty collection in C because array lengths are stored separately from arrays and there is no advantage to allocating an empty array. But a null is not the right answer all the time in all languages.
Best Answer
I very much want a C# language feature that lets me safely do x.Prop.SomeOtherProp.ThirdProp without having to check each of those for null. In one codebase where I had to do those sorts of "deep property traversals" a lot, I wrote an extension method called Navigate that swallowed NullReferenceExceptions and instead returned a default value. So I could do something like this:
The downside of this is that it has a different code smell: swallowed exceptions. If you wanted to do something like this "right", you could take the lamdba as an expression, and modify the expression on the fly to add the null checks around each property accessor. I went for "quick and dirty" and didn't implement it this "better" way. But maybe when I have some spare thought cycles I'll revisit this and post it somewhere.
To more directly answer your question, I'm guessing the reason this isn't a feature is because the cost of implementing the feature exceeds the benefit from having the feature. The C# team has to pick and choose which features to focus on, and this one hasn't floated to the top yet. Just a guess though I don't have any insider info.