I'm comming from Java world mainly. So, C# properties do look nice.
I know that with C# 3.0 or above I can use Automatic Properties. I like it even more :).
My question is about a (maybe older) code where I can see this:
private int age;
public int Age {
get { return age; }
set { age = value; }
}
Why do I need the private field age? What I'm I really hiding here?
EDIT:
I completely understand the need for the getter and setter. I mentioned that I'm comming from Java world and doing开发者_如何学Go this all the time.
I do understand that Automatic Properties in C# 3.0 or above are syntatic sugar. But maybe my question has a simpler answer. Does it means that (bellow C# 3.0) the property doesn't hold any value. So it must get the value from some other field?
Older versions of C# didn't have automatic properties, so you had to declare your variables that the properties acted upon like in your example. These days, the same code could be expressed as:
public int Age { get; set; }
I think that answers your question. However, if you are asking "why not just have public int Age; and let programmers set the value on the field directly?", then:
First thing to keep in mind is that property accessors are compiled into methods. This means that it has a different ABI from just reading/writing to a class member variable, even though it may syntactically look the same as if you had:
class Fu {
public int Age;
}
So, what this means is that if, at some point down the road, you need to add some notification that the Age field has changed - if you are using properties, you can easily add this notification logic to the property setter without breaking ABI.
public int Age {
get { return age; }
set { age = value; NotifySomeOtherCode (); }
}
If you start off with a public field, then later changing it to a property will change the ABI which is bad for any program(s) that may depend on your assembly. So it's better to start off with properties.
Hopefully I'm making sense...
The automatic properties were not supported in older versions of the C# compiler.
The above code is more or less equivalent to this (assuming that the field is never actually used directly):
public int Age {
get;
set;
}
In this case you don't require it. If you ever need to do anything else in the setter or getter, though, the automatic property won't work -- you'll need the private field to manipulate.
The bog-standard answer would be "encapsulating the implementation detail of how and where the age is stored".
For retrieval purposes, a more realistic example might be that one day, you could potentially want to access the value in a way that means direct access isn't so good. For example, if it's a value that you might be caching elsewhere, or if it's a calculated value.
In terms of encapsulating the setting process, it means you can embed some model-level validation into the setter; if someone tries to set a conceptually invalid value, you can throw an IllegalArgumentException
and reject it.
In these cases, the encapsulation means that all your existing code doesn't have to change because you had to wrap up the value in something.
Automatic properties in C#, when compiled, end up functionally exactly the same as the above code. The compiler generates a backing field for you.
So you do need something backing a property - a field or some code - it's just that it's taken care of for you with the shortcut of auto-properties.
Properties are just a nice way to write a pair of a get and a set method. In Java you would do this:
private int age;
public int getAge() { return age; }
public void setAge(int value) { age = value; }
You need the private field to store the age somewhere -- getAge and setAge are just methods.
The same applies to C# to versions before 3.0:
private int age;
public int Age
{
get { return age; }
set { age = value; }
}
This is a get and a set method, just nicely paired up so you can write x.Age = 21
instead of x.setAge(21)
.
With automatic properties, the C# compiler generates the private field for you (but it's still there!):
public int Age
{
get;
set;
}
The benefit of automatic properties is that you don't have to create the backing field manually yourself anymore.
The benefit of the manual version is, that you can add additional logic to the get and set methods, for instance, parameter validation:
private int age;
public int Age
{
get { return age; }
set { if (value < 0) throw new ArgumentException(); age = value; }
}
Maybe you want to change the behaviour of the setter or getter at a later point. e.g. log that the value was changed from outside. this would not be possible with a public field without properties
private int age;
public int Age {
get { return age; }
set {
age = value;
Log("value of age changed");
}
}
With a public field age
, you had to log this everywhere in the code where you change the value of age.
In this case you aren't hiding anything but it will give you the freedom to add get/set logic to your private field later. So anyone who uses the property wont notice the difference in the future.
In the simple case nothing. However you are making it easier to maintain the interface to the class should the implementation of either of those two methods require additional code.
Take for instance if you need to add a changing event to the setter.
public int Age {
get { return age; }
set {
if ( age != value) {
age = value;
OnAgeChanged();
}
}
}
You can do this with a property and not break client code. A field does not have this advantage.
With the automatic properties, you don't need to do this. There's nothing wrong with it, but with automatic properties you'll still have your property signature, which is the important thing. Before automatic properties, you had to have a backing field for your property. As long as you have an automatic property, you can later change it to the format with an explicit backing field, and the signature stays the same.
But, there's nothing wrong with it. Except that the convention is becoming more to call the private backing field "_age".
(I assume you know why you want to have a property, whether automatic or not, instead of a public field. The reason is that the object has a different signature if you change form public field to public property, so it's safest to just start off with a property, even if there is no extra logic.)
Getters and Setters are the public interface that other classes interact with. In complex systems you usually end up doing validation and other work inside the getter and setter.
The private field is for internal use. If you need to change the value from inside the class but bypass all the extra work you would change the private variable.
精彩评论