Skip to content
loading...

Are properties harmful?

Ryan Westlund on February 09, 2020

By properties, I mean attributes with getters and setters that use the syntax of a plain attribute instead of the syntax of a function, like this: ... [Read Full]
markdown guide
 

Automatic properties in particular (like what C# supports) eliminate the standard boilerplate in cases where it isn't needed. It also saves clients needing to call functions, which makes chaining possible / easier, even where logic is required. Finally, there's simply less code to maintain, and therefore less chance of things breaking later.

 

I don't know C# or what you mean by automatic properties, so I guess I can't follow that one :/

 

In C#, properties are just special methods which have a "get" and a "set" component. They technically don't have to do anything in particular, but the traditional old-fashioned way to write them is to wrap the getter and setter around a field:

public class Foo {
    private string _name; // This is a field
    public string Name { // This is a property
        get { return _name; }
        set { _name = value; }
    }
}

This is clearly redundant and a lot of unnecessary typing. So they introduced "auto-properties", where the following is just syntatic sugar for the above - absolutely identical result:

public class Foo {
    public string Name { get; set; }
}

You may ask, why don't you just have a public field, like:

public class Foo {
    public string Name;
}

You can do that, but what happens later when you realize that you always want the Name value to be upper-case? You would have to make a change to the structure of the class, which could potentially break other things. If you went the property way, you could simply change the "setter", and the code structure would be identical, just a change to the implementation:

public class Foo {
    private string _name;
    public string Name {
        get { return _name; }
        set { _name = value.ToUpper(); }
    }
}

The equivalent way of doing this with methods is:

public class Foo {
    private string _name;
    public string GetName() { return _name; }
    public string SetName(name) { _name = name.ToUpper(); }
}

Which isn't really bad, but it does make it a little bit more difficult to distinguish between methods that are strictly about accessing data, vs. methods that actually "do" something. Plus, like in my answer, you'd have to do even more work to serialize an object into something that returns {"Name":"John Doe"}, when the property way just "works".

 

I meant property declarations having only a type, name, and the keywords get and set within the definition, leaving the compiler to generate an implementation for us.

 

Serialization with lazy loading is one use case. A property's "getter" may check to see if its underlying field is populated, and if not, then populate it and return the result. If you only used regular methods to get and set, then the fields may not be populated yet if you've never called the get method.

In C#:

class Foo
{
    private string _name;
    public string Name 
    {
        get { return _name ?? (_name = SomeService.GetName()); }
        set { _name = value; }
    }
}
 

I see the idea, but is it so bad to just call a method from the outside? I would approach this by having a ReadName method that would do the same as the property getter. (And maybe turn the setter into a method too.) It might be a couple more lines, but I feel like it would be clearer.

 

Here's a bigger serialization example. If you didn't have properties, then you'd have to remember to manually set the DisplayName value, the DateOfBirth_Formatted value, and the CanDrive value, every time you wanted to serialize the object. These three are "get" properties (the arrow syntax is shorthand for a "get" property with no "set") which are basically the same as methods, but because they're properties, they're executed when the data is serialized, and included in the output, with no extra work.

The FirstName, LastName, State, and DateOfBirth properties could be raw data from the database table.

I use this type of thing when I want to pass data from the web server to the client, when I don't want to have to deal with formatting the data in javascript.

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string State { get; set; }
    public DateTime DateOfBirth { get; set; }
    public string DisplayName => $"{FirstName} {LastName}";
    public string DateOfBirth_Formatted => DateOfBirth.ToString(@"MM\/dd\/yyyy");
    public bool CanDrive => DriveService.CanHaveDriverLicense(DateOfBirth, State);
}

But in the end, you definitely have a point. Whatever is clearer to you and the people you work with, is very possibly the best way to go. You'll be the ones maintaining the code in the future. But just keep in mind that field-backed properties aren't going away, so it may be worth the time to get used to them because you will see them whenever you maintain someone else's code.

Ah, I see. Serialization is a good point.

 

The explanation that I got from Raymond Hettinger was that if you change from a circle that stores a radius to one that does a diameter then you could use these to keep from breaking any code that depends on radius.

code of conduct - report abuse