1

In C#, when a field getting or setting requires logic, we use properties. For example:

private int _age;
public int Age
{
    get
    {
        Console.Writeline("Club member is {0} years old", _age);
    }
    set
    {
        if(value > 0 && value < 120)
        {
            _age = value;
        }
        else
        {
            Console.Writeline("We do not accept unborns nor immortals to our club.");
        }
    }
}

When no logic is required, we could use the very concise auto-implemented properties:

public string Name {get; set;}

Thos are very similar to public fields since you could read and change their values from anywhere. There are, however, some differences, as Michael Stum summarizes very well Jeff Atwood's article:

  • Reflection works differently on variables vs. properties, so if you rely on reflection, it's easier to use all properties.
  • You can't databind against a variable.
  • Changing a variable to a property is a breaking change. For example:

    TryGetTitle(out book.Title); // requires a variable
    

As I see it, those are very technical differences: public fields have some advantages over auto-implemented properties and vice-versa, but fundamentally, in an OOP point-of-view, they are very similar: fields which can be changed from any class, and that, as far as I know, violates encapsulation.

So why public fields considered evil due to the encapsulation violation while auto-implemented properties are so great?

Michael Haddad
  • 2,651
  • 3
  • 17
  • 27
  • 4
    "public fields considered evil ... while auto-implemented properties are so great" -- *citation needed*! – Martin Ba May 13 '16 at 07:49
  • @MartinBa - My English is no very good, so I do not understand if you are joking about my question or my assumptions, or just trying to help. If you are making a joke - it is not nice. I am just trying to learn. If not, please explain what do you mean. Thanks. – Michael Haddad May 13 '16 at 07:52
  • 1
    possible duplicate of [Why are public and private accessors considered good practice?](http://programmers.stackexchange.com/questions/120497/why-are-public-and-private-accessors-considered-good-practice) – gnat May 13 '16 at 08:03
  • How it is a duplicate? – Michael Haddad May 13 '16 at 08:04
  • 2
    @Sipo - What my comment said was: Your Question _claims_ that "public fields considered evil ... while auto-implemented properties are so great". That is, the claim is that they're considered differently based on OO merits (and not on the technical merits you cited). This claim needs to be backed up, (links, or more explanation on your part) or otherwise the question is moot. – Martin Ba May 13 '16 at 08:20
  • @Sip - also: https://www.explainxkcd.com/wiki/index.php/285:_Wikipedian_Protester – Martin Ba May 13 '16 at 08:23

2 Answers2

14

Properties do not violate encapsulation, because they hide the underlying implementation.

When you access a property, you don't need to know how exactly it is implemented: whether it's an auto-property, whether it accesses some other object, or anything else. It also means that the implementation can be easily changed and all users of such code will still work.

This does not apply to fields. The user always knows how they are implemented and that implementation cannot be changed without breaking users of the code (at least potentially).

Daniel T.
  • 3,013
  • 19
  • 24
svick
  • 9,999
  • 1
  • 37
  • 51
  • You have confused encapsulation with abstraction. – David Arno May 13 '16 at 17:37
  • @DavidArno [Encapsulation](https://en.wikipedia.org/wiki/Encapsulation_%28computer_programming%29): "A language mechanism for restricting access to some of the object's components." Using properties does restrict access to the underlying field. – svick May 13 '16 at 17:38
  • 6
    I think what svick is saying is that with properties, the class' external api is not exposing the private field that the class is actually using to store the data. You are required to go through the property to change state, or more accurately, to _ask_ the class to change its state. What the property getter and setter do, if anything, is _encapsulated_ in the class. That's more than an abstraction. – Eric King May 13 '16 at 23:28
  • Thanks, this is a very good answer. I chose @Joel Harmon answer due to the level of detail. Thanks again. – Michael Haddad May 15 '16 at 06:21
4

The Question

The question is

So why public fields considered evil due to the encapsulation violation while auto-implemented properties are so great?

The answer to that question is covered in one of the technical points you note

Changing a variable to a property is a breaking change

If you publish any class to anyone (even your future self), you're bound to either keep to that interface or break an arbitrary amount of code that depends on it. Forever.

Encapsulation solves this issue by providing (or rather, describing) a way to be sure you can make changes to the implementation in the future without breaking any code outside the class. That is, using public fields binds you to them indefinitely, whereas auto-generated properties have the ability to change in the future without breaking calling code.

I'd like to note here that turning a field into a property is not a breaking change in all programming languages, but it is in C#.

Encapsulation

Implied in the question is another one I'd like to tackle about whether or not properties can provide encapsulation.

Wikipedia defines Encapsulation as two related but separate concepts:

  • A language mechanism for restricting access to some of the object's components.

  • A language construct that facilitates the bundling of data with the methods (or other functions) operating on that data.

The question asserts that

[properties are] fields which can be changed from any class, and that, as far as I know, violates encapsulation.

I reject this assertion based on both of Wiki's definitions. Let me give an example straw man scenario and then ask some questions about it to investigate.

I've made a class called Temperature. It has public properties for getting and setting its temperature in Celsius, Fahrenheit, and Kelvin. It will do any conversions between them simply by writing one than reading another.

Question 1: How is Temperature used?

  1. Reading and/or writing the properties directly, per the above interface description

  2. Reading and/or writing some internal state that isn't part of the public interface specified above

  3. Some other answer that I'm unaware of

Question 2: How is Temperature implemented?

  1. Each property has a backing hidden variable, with each setter updating all three backing variables. Getters just echo the variable.

  2. There is one backing variable (in Rankines) updated by all three setters. Each getter converts from Rankines to the appropriate unit on the fly.

  3. Temperature stores only a GUID. Any get/set requests are passed with the GUID to a web service, which handles the actual business of conversion.

  4. It's impossible to tell from the interface defined, but any of the above would work (modulo network exceptions).

  5. Some other answer that I'm unaware of

The answers I would pick are 1 and 4. That is, properties defined some public interface to the class, but obfuscated how the class was actually implemented. Properties satisfy "restricting access to some of the object's components" by hiding what those components even are. In conjunction with the class itself, they also help with "facilitates the bundling of data with the methods (or other functions) operating on that data" by being able to share information among themselves.

TL;DR: Properties can (and commonly are) used to support encapsulation.

Joel Harmon
  • 1,063
  • 7
  • 10