问题
New to C#, and I understand that encapsulation is just a way of "protecting data". But I am still unclear. I thought that the point of get and set accessors were to add tests within those methods to check to see if parameters meet certain criteria, before allowing an external function to get and set anything, like this:
private string myName;
public string MyName;// this is a property, speical to c#, which sets the backing field.
private string myName = "mary";// the backing field.
public string MyName // this is a property, which sets/gets the backing field.
{
get
{
return myName;
}
set
{
if (value != "Silly Woman"){
myName = value;
}
}
}
But I've been seeing code in c# which just looks like this:
public string MyName { get; set; }
Why would you just have a get and set with nothing in there, - isn't that the same as just declaring your private backing field public? If you can just get and set it from outside, why wouldn't you just do it directly?
回答1:
Indeed, creating an auto-property as follows:
public string Name { get; set; }
is identical to building a property backed by a field:
private string _name;
public string Name {
get { return _name; }
set { _name = value; }
}
The point of these properties is not to hide data. As you observed, they don't do this. Instead, these properties can do other stuff instead of just working with a field:
public string Name {
get { return _name; }
set { if (value == null) throw new Exception("GTFO!"); _name = value; }
}
Another thing is, you can make properties virtual:
public virtual string Name { get; set; }
which, if overridden, can provide different results and behaviours in a derived class.
回答2:
By using public string MyName { get; set; }
, you leave an ability to change its logic later without the need to recompile/change other code that uses your property.
For example, if you are making a library and v1 uses a field and v2 uses a property, applications that work with v1 will not work with v2 without recompilation (and, potentially, code changes if they are written in some .NET language that has different syntax for accessing fields).
Another important difference is in serialization scenarios -- a lot of them do not support fields. Also any interface that requires a property can not be implemented without using one, but depending on interface it may not be required to do any additional checks/logic in it.
回答3:
Because it is easier to change the Code if you want to add the checks/tests later on. Especially if you have many inheritance and many classes in your code it is very hard to change the implementation from a public variable to a public Property.
Moreover you can add to the get and set within the property different attributes, e.g. if you are using reflection. The get and set of the property are internally different methods. If you have just a public variable /field it is not possible to added different properties to the different access ways.
回答4:
Yeah, but you can easily change it to:
public string MyName { get; private set; }
Plus, properties are used in other scenarios, like DataContract
s and Serialization... so, this is a nice feature... (Mostly, syntactic sugar. I think) EDIT: I take that back.. you can apply virtual to it, so it's not the same
回答5:
It makes it easier to add logic later. If you have a class that has a public field that you want to change to a property, you have to recompile everything that uses your class. That's a key point that I didn't understand initially.
If you have a class:
public class MyClass
{
public string MyString;
}
You could access the value like this:
var myClass = new MyClass();
string s = myClass.MyString;
Now change that to a property:
public class MyClass
{
public string MyString { get; set; }
}
How is it accessed? The exact same way:
var myClass = new MyClass();
string s = myClass.MyString;
So no big deal, right? Well, actually....
Properties are actually compiled into getter and setter methods:
get_MyString()
and set_MyString(string value)
So the two methods do produce different compiled code. Now if all your code that uses this class is in the same project, is not as big a deal, because it will all be compiled together. But if you have an API library that you've distributed, it can be a much bigger deal to update.
来源:https://stackoverflow.com/questions/17667250/encapsulation-c-sharp-newbie