Click here to Skip to main content
15,314,644 members
Articles / Programming Languages / C#
Tip/Trick
Posted 6 Jan 2016

Tagged as

Stats

13.9K views
1 bookmarked

Asymmetric Property anti-pattern

Rate me:
Please Sign up or sign in to vote.
3.45/5 (11 votes)
6 Jan 2016Ms-RL2 min read
Property is a simple idea, but like many others can be misused. This tip describes asymmetric property anti-pattern and shows why properties should be symmetric to be maintainable and intuitive.

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#:

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#:

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:

C#
object.PropertyName = object.PropertyName;

Breaking symmetry of a property can cause various bugs and makes the property usage counterintuitive.

License

This article, along with any associated source code and files, is licensed under Microsoft Reciprocal License

Share

About the Author

I’m a full stack developer specialized in design and implementation of web portals using Microsoft technology stack (ASP.NET, ASP.NET MVC, C#, Entity Framework). I put emphasis on SOLID craftsmanship and strive to keep my code clean. Because I know how expensive technical debt can be. Because I understand my job is not to write code, but to solve problems. Because I want to help people to be more effective through the software.

Comments and Discussions

 
QuestionWhat's you view on constrained sets? Pin
Paulo Zemek6-Jan-16 10:24
MemberPaulo Zemek6-Jan-16 10:24 
I completely agree that your example is a terrible practice.
Yet, what do you think about constrained values?

For example, a property that is constrained between 0 and 100. If I set -1, instead of an exception, it is simply set to 0? Or if I set it to 200, it is actually set to 100.

In this case, reading the value from one object and applying it to another will not have any issues, yet a call to set 200 and then a get will return 100.

Do you have any comments on this situation?

AnswerRe: What's you view on constrained sets? Pin
Arkadiusz Kaɫkus8-Jan-16 5:06
MemberArkadiusz Kaɫkus8-Jan-16 5:06 
GeneralRe: What's you view on constrained sets? Pin
Paulo Zemek8-Jan-16 7:38
MemberPaulo Zemek8-Jan-16 7:38 
GeneralRe: What's you view on constrained sets? Pin
Arkadiusz Kaɫkus8-Jan-16 22:21
MemberArkadiusz Kaɫkus8-Jan-16 22:21 
GeneralRe: What's you view on constrained sets? Pin
Paulo Zemek9-Jan-16 19:23
MemberPaulo Zemek9-Jan-16 19:23 
GeneralRe: What's you view on constrained sets? Pin
Arkadiusz Kaɫkus9-Jan-16 23:56
MemberArkadiusz Kaɫkus9-Jan-16 23:56 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.