-3

I am trying to understand private fields in C#. Coming from a Java background, I am just a little confused.

Here is my class:

   class Student
    {
        public int Age { get; set; }
        public string Name { get; private set; }

        public int x = 6;

        public Student() // Empty constructor
        { }

        public Student(int age, string name)
        {
            Age = age; // Work with Age as it is a field
            Name = "John"; // OK: accessing a private setter
        }
    }

The auto-implemented properties Age and Name both can be accessed the same way the public x can be accessed. I can write student.x, just as I can write student.Age.

I know that the compiler creates the private fields for Age and Name, but since I can access it the same as the x, how is this private?

In Java, you have to call a public method that returns the private field, but with C#, it just seems like this defeats the purpose of a private field.

Basically, how does this benefit us at all? Why not just make everything public if we are going to set public setters and getters on Age and Name anyways? Logically, I just don't see the benefit or how this is actually private?

mastercooler6
  • 377
  • 2
  • 16
  • 1
    Properties are just syntax over methods. You can do `public int X { get { } set { }}` and then you can do something like `obj.X++;` whereas with methods you'd have to do `obj.SetX(obj.GetX()++);` so it gives you a better experience while still keeping the backing fields private so you can add any implementation you want while maintaining backwards compatibility. – juharr Jun 07 '22 at 12:28
  • I see what you are saying, but still feels weird. When you say `while still keeping the backing fields private`, it still seems like the backing field is public because it is directly connected to the public getter/setter. – mastercooler6 Jun 07 '22 at 12:38
  • 2
    Please look up computed properties, properties can have logic inside them and they are used for Databinding in WPF, there are many application for properties while field will just hold the value for you and does nothing. – Lokanath Jun 07 '22 at 12:38
  • @mastercooler6 For auto properties there is a hidden private backing field created automatically. This was done to get rid of a bunch of boiler plate code when all you want is to set and get from a private backing field. – juharr Jun 07 '22 at 12:42
  • 1
    @mastercooler6: The point is that you can (a) change your auto-property to a "regular" property and then (b) replace the backing field with something else *without changing the signature of your class*. You can't do that with a public field. – Heinzi Jun 07 '22 at 12:45

2 Answers2

0
public int Age {get; set;}

is equivilent to

private int _age;
public int Age { get { return _age; } set { _age = value; }

Isn't the first easier to write? Doesn't it follow the same best practices from Java?

And you can also use the private set or init set to lock them down easily. I think it saves lots of typing and makes it easy to modify the get/set command latter if needed.

Richard Hubley
  • 2,180
  • 22
  • 29
0

Basically, how does this benefit us at all?

Initially, it doesn't. But it allows you to create a stable API:

Imagine that, at some point in the future, you want to change the way Age works. You decide that you no longer want to internally store the age of a person, but rather their birth date and calculate the age instead. Or you want to create a log entry every time the Age property is accessed.

If Age is a field, you are out of luck. But if Age is an auto-implemented property, you can just change it to a "regular" property, make your desired changes in the getter and then ship an updated version of your library without breaking backwards compatibility, since that modification is neither a source-level break nor a binary-level break. Your clients can just replace the old version of your library with the new one without having to recompile their applications. (Changing a field to a property would always be a binary-level breaking change and, in some cases, also a source-level breaking change.)

Heinzi
  • 167,459
  • 57
  • 363
  • 519