1

An example of Auto-implemented properties in C# is for example:

 public double TotalPurchases { get; set; }

I understand what they are, and as they say the "compiler creates a private field that can only be accessed through get and set.

My question is what is the point of this?

I mean in other languages, the point was: You have a variable that you make private and then you declare some functions public through which you can access that variable- NEVER directly. Why? Well because then you can implement that "variable" the way you want it and the user of your class is oblivious to that, he just gets and sets what he sees is a property of the class.

But here, although you have a private variable that can be accessed only through get and set (same as above) you also have a very public variable that actually you access directly, defeating the purpose of get and set in the first place.

I mean if you are going to do

cust1.TotalPurchases += 499.99;

why not just have

public double TotalPurchases;

and be done with it??

EDIT: This question has been marked as a "possible duplicate" which in my opinion is not, and i will try to explain -in my rather limited english- why it is not.

The author of the "possible duplicate" originally wrote a way that broke totally encapsulation. Later he confessed that he "couldn't bear writing all that " so he just used public fields. After all he didn't care about encapsulation in the first place.

My post is the total opposite. I want to keep encapsulation, since as I previously explained this gives me the liberty to implement TotalPurchases as I see fit. I may use a variable, but I might get that from a DB, or calculate it through a Neural network. The thing is I don't want the user to be oblivious to this.

But, if I have to use get and set as explained I am forced to declare a public variable right? or if I do this

private double TotalPurchases {get; set;}

are these get and set public? I suspect they are not.

So my question is what is the point of breaking encapsulation?

KansaiRobot
  • 7,564
  • 11
  • 71
  • 150
  • You *don't* access it directly, you access it through the getter and the setter, and those can be implemented in any way you see fit. To the *client*, a field and a property appear to be the same thing, yes. If that's unwanted (because the getter and setter are very expensive, for example) then don't use a property, use explicit methods. – Jeroen Mostert Jul 05 '17 at 09:46
  • `private double TotalPurchases {get; set;}` creates a private property with non-public getter and setter. So this is not visible on the outside at all. The point about auto-properties is that you have a *property* without having to do all the boilerplate of managing the private backing field yourself. You are using a property instead of a field since that allow you to change the implementation later without breaking the contract. – That’s all explained in the linked question. I also don’t get what you mean with “point of breaking encapsulation”. – poke Jul 05 '17 at 09:46
  • @poke When you say "change the implementation later" does that mean that I can do something like `public double TotalPurchases{ get{//domystuff};set{//domystufftoo}}`. I mean otherwise I don't get about this later stuff – KansaiRobot Jul 05 '17 at 09:50
  • 2
    Yes, switching from auto properties to your own implementation where you do *whatever* (getting/setting the values in a field, querying a database, a webservice, throwing a die, …) is not a breaking change for the contract. On the outside, it’s still a property and the implementation is not visible from the outside. – poke Jul 05 '17 at 09:51
  • `public TotalPurchases` is not always a drop-in replacement for `public TotalPurchases {get; set;}` As an example, see https://stackoverflow.com/a/19851801/34092 - not that this functionality **only works with properties**. This is an example where auto-implemented properties would work, but fields would not. – mjwills Jul 05 '17 at 10:28

1 Answers1

3

Changing from a field to a property is a breaking change for libraries because the CIL to access a field is different from the CIL to access a property. If you want the benefits of properties when you write a library (which is that you can replace the auto-synthesized getter/setter with one that does something else) without needing to rebuild the world, you need to plan for it and use the { get; set; } syntax.

As people have already outlined in the comments, there are also some differences in reflection, but they usually aren't things that you want to do in and of themselves.

zneak
  • 134,922
  • 42
  • 253
  • 328
  • so, what I am understanding is, that since *in the future* I can change the implementation of a get/set, I should write the auto-synthesized it now? Doesn't it break the encapsulation? – KansaiRobot Jul 05 '17 at 23:54
  • @KansaiRobot, what breaks encapsulation in this exactly? – zneak Jul 06 '17 at 00:03
  • in my example, the user can see there is a variable called TotalPurchases...isn't the point that he does not see this and can only use getPurchases or setPurchases to interact? – KansaiRobot Jul 06 '17 at 00:30
  • @KansaiRobot, I'm still not sure I see where you're going with this. Are you saying that properties aren't proper encapsulation because they aren't methods? – zneak Jul 06 '17 at 00:44
  • perhaps is that I learned bad. I was told never-as most as I can- to let the user set an object variable directly. Make them private. If the user wants access to them, they should use methods. In that way I can do whatever I want with that variable provided that the get set method behavior does not change. – KansaiRobot Jul 06 '17 at 00:57
  • @KansaiRobot, were you taught that the *syntax* of `obj.Foo = 4` is evil? You probably realize that anything that you could put in a `SetFoo` method could also find its way in a property's `set { ... }` block. If it's just a matter of two syntactically different ways to get the same code to run, I don't think that it should bother anyone. – zneak Jul 06 '17 at 01:13
  • Having a *field* instead of a property makes things different. The compiled code that accesses a property is identical to the compiled code that calls a method. However, the compiled code that accesses a field is different and it doesn't allow you any spare room for binary-compatible changes, if you need to make any. – zneak Jul 06 '17 at 01:17