That’s a well known question. Actually, I knew the difference between methods and properties long ago. Despite of that, recently I stumbled upon my own incorrect choice between those semantic constructions. That’s why I decided to write this post – in order to solidify the understanding of the difference between property and method.
Method vs Property fail in BCL
The most notorious fail of creating a property inside the BCL (FCL) in .NET instead of a method is the DateTime.Now property. In my opinion, this particular case is not the worst in history, though it’s an embarrassing one. So, what’s wrong with that the DateTime.Now is implemented as a property rather than a method? This isn’t wrong from the point of the actual implementation, it is implemented correctly, the point is that this is semantically wrong from the API design perspective. If every time the getter of a property returns different values, then this is a method, not a property. Why? Because a property is an attribute of an entity. For example, Year is an attribute of a Date, so it would be correct to get the year as it follows: DateTime.Now().Year. Yes, that’s it, that’s how it should look like, not like a chain wreck – DateTime.Now.Year. By the way, similar by the case Guid.NewGuid() member is implemented as a method. In this case, the word “New” dictates that this should be a method, but for example they could have named it Guid.Next and even in this case it should be a method, as well as the DateTime.Now!
Method or Property. How to reason about
You should create properties as simple as you can. They should not throw exceptions in getters, they should not connect to a database and they should not be asynchronous.
What I exactly stumbled upon recently is the latter case. I know I will provide a stupid example of shitty code, but I’m sure there can be tons of similar cases without anti-patterns. So, there was a simple window which was implemented without MVVM and all that stuff. In the .xaml.cs file was a string property which in it’s setter set the text in a text block and for some reason it did it asynchronously using Application.Current.Dispatcher.BeginInvoke() method.
[code language=”csharp”]
public string ImportantTxt{
get { return TxtBlock.Text; }
set {
Application.Current.Dispatcher.BeginInvoke(() = > {
TxtBlock.Text = value;
});
}
}
[/code]
Ten minutes I couldn’t understand why the following code didn’t work as expected:
[code language=”csharp”]
string txt = ExternalService.GetTxt();
ImportantTxt = txt;
if (ImportantTxt == "expectedValue") {
//do something
}
[/code]
Don’t think about the sacred meaning of this code. The point is that the caller of a property setter never expects that it will not be changed immediately. In this case the setter unintentionally deferred it’s work. If the property is tightly semantically coupled with the UI and you want to use such an async construction, then the property at least should not be a part of a public contract.
To recap I should say that properties and methods are very different from the perspective of usage scenarios (use cases). Say “No” to any multi-threading, synchronization, external API calls, CPU-intensive calculations and even simple, yet each time returning different results pieces of code inside of your properties.
Subscribe to my blog, don’t miss the next exciting post.