Introduction
Properties are well known elements of modern programming languages. They are intended to increase encapsulation and consistency of objects. Unfortunately, properties can be misused.
Basically, a property is a special sort of class member, intermediate between a field and a method. It can be read and written like field, but reading operation calls get
method and writing operation calls set
method of the property.
Example syntax in C#:
private int myVar;
public int MyProperty
{
get { return myVar; }
set { myVar = value; }
}
Because myVar
(outside of a class) can be accessed only through MyProperty
, it is encapsulated. With custom implementation of get
and set
methods, a software developer is able to provide for instance validation of myVar
field and keep data of a class consistent.
Anti-pattern
Properties are accessed like variables, but often their behavior is completely counterintuitive. This leads to confusion and bugs. The most important thing when it comes to property design is its symmetry. If setting (or getting) property entails some additional changes in other objects - it’s dangerous, but when setting property and reading it again gives a different value than has been set - it’s complete disaster.
Example of asymmetric property in C#:
using System;
namespace AsymmetricPropertyExample
{
internal class Person
{
private string firstName;
public string FirstName
{
get { return firstName; }
set { firstName = "Name: " + value; }
}
}
internal class Program
{
private static void Main(string[] args)
{
var person = new Person
{
FirstName = "Steve"
};
Console.WriteLine(person.FirstName);
person.FirstName = person.FirstName;
Console.WriteLine(person.FirstName);
Console.ReadKey();
}
}
}
Result of running the example code:
Name: Steve
Name: Name: Steve
It may seem absurd because at first glance this kind of assignment is unusual. It’s not true. The same bug will appear during assigning FirstName
of one Person
object to another. This kind of design can cause problems during mapping operations too.
Of course, this is a highly theoretical example, but in real world solutions, bugs caused by asymmetric properties are more complicated and sometimes tough to find. Often, developers assume that a class they design at a given time will be used only in one context, in a way they have just implemented. It’s obvious violation of open/closed principle and generally lack of imagination about future development of a particular software project. Anyway - one should always assume that his classes and properties could be used by another person. No one expects properties to work in an asymmetric way because they are perceived as plain variables. Changing some internal state of a class (or throwing exceptions) on property change isn’t as confusing to developer as asymmetry.
Here - https://msdn.microsoft.com/en-us/library/ms229006.aspx - Microsoft gives property design guidelines. Author(s) don’t mention about symmetry of properties, but there are many good principles to follow (omitted in this article to keep it concise).
Conclusion
Properties are widely used in modern programming languages. There are various property design rules, but one simple thing is often ignored - properties should be symmetric.
In other words, this kind of assignment shouldn’t change value of property:
object.PropertyName = object.PropertyName;
Breaking symmetry of a property can cause various bugs and makes the property usage counterintuitive.