I want to understand a simple thing.
I am reading a lot of questions, answers about Encapsulate in Unity and C#.
It is all talking about get
/set
and most of the answers saying that
the top benefit of get
and set
is to stop mistyping or something I write in any other script to access my variable and make problem for my program.
So, if I am really focused and I don't make a mistake like get
/set
becoming null
! I mean, there is no other real benefits.
Also, I see that property force me to rewrite the variables name, so much
Like this:
private int health
public int health { get; private set; }
So the result is that I make more complex code. I make more same names in my script, that is not dangerous?
You're example isn't working because health
is the same variable twice. The common convention is to use _health
or health
for the backing field and Health
for the property (get
/set/
). Also, there's nothing stopping you from doing:
private int backingField;
public int OtherProperty { get { return backingField; } }
public int Property => backingField; // Does same thing as above
It would just be very confusing for you, your future self, and your coworkers.
However, in your case, you can just do this:
public int Health { get; private set; }
So, if I am really focused and I don't make a mistake
This is a really bad mindset. You're gonna shoot yourself in the foot if you keep doing this mindset, because you can't focus on everything at the same time. The brain can only have so much information loaded at once. The idea is to not allow yourself to make mistakes.
My programmer professor once said that that mindset is like leaving your baby on one lane of the highway, and if a car comes you just move it to the other lane. You could do that forever, or you could just not have your baby anywhere near the highway.
Visual Studio makes it really easy to rename things and you only need to do that once. The better power of get
/set
is to make sure the data is valid. For example
private int _age = 0;
public int Age
{
get => _age;
set
{
if (value > 0)
_age = value;
}
}
This code will prevent the user from setting Age
to be a negative number, because that's impossible.
Properties are amazing and there's lots of cool things you can do with them, like this:
public struct Rectangle
{
public int X, Y;
public int Area => X * Y;
public Rectangle(int x, int y) => (X, Y) = (x, y);
}
public int Area => X * Y;
is a property, though it doesn't look it. It's the same as:
public int Area
{
get
{
return X * Y;
}
}
What's cool is that Area
only has a getter therefore the value of it can't be changed. Area = 3
won't work. This is ideal, because that would make invalid data.
Effectively, all Area
is is syntactic sugar for a method GetArea() => X * Y;
, but we instead don't use Get
prefix or the ()
at the end.
In summary, properties (get/set) are useful to make the setting of the variable private or protected to prevent invalid data from leaking in, having something fire when the setter is used to make sure the new data is valid, or having something that looks like a readonly variable but it actually executes a quick calculation to get the data.
They are great for encapsulation in that sense.
Edit: As Draco18s pointed out, they are also useful for interfaces, which are like classes, but one of the differences being they can't have fields. They can however, have properties, as, under the hood, properties are just methods.