Suppose there is this:
private int a { get; set; }
What is the point if I can do this:
public int a;
Suppose there is this:
private int a { get; set; }
What is the point if I can do this:
public int a;
See what advantages the property has over the field.
If your property is defined as:
public int A { get; set; }
- Of course, there are no immediate benefits. But the benefits will come later.
You can hang your logic to write and read the value. Applications can be the sea. For example, you want to count how many times a value is read:
private int a; private int readcount_a = 0; public int A { get { readcount_a++; return a; } set { a = value; } }
You can make a trigger to change the field:
class Data : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private int a; public int A { get { return a; } set { if (a == value) return; a = value; RaisePropertyChanged(); } } private void RaisePropertyChanged([CallerMemberName] string propertyName = null) { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } }
You can log all changes to the field:
public int A { get { return a; } set { Trace.TraceInformation("Changing value of a from {0} to {1}", a, value); a = value; } }
You can hang a validation value on writing when writing, or lazy initialization while reading.
class Data { private string a = null; public string A { get { return a ?? (a = LazyComputeInitialA()); } set { if (value == null) throw new ArgumentException(nameof(A) + " cannot be null", nameof(A)); a = value; } } }
In the end, you can not use memory for a value, if in most cases it is the same (as was done with DependencyProperty
):
class Data { static Dictionary<Data, int> aValues = new Dictionary<Data, int>(); public int A { get { int result; if (aValues.TryGetValue(this, out result)) return result; else return -1; // default value } set { aValues[this] = value; } } }
You want to make different degrees of visibility for the getter and setter, so for example, only your class and its heirs can set the value, and everyone can count. (This is perhaps the best use of the properties for my taste.)
public int A { get; protected set; }
You may not define a setter at all, and return some value calculated by you:
public int A { get { return b + c; } }
(however, this can be done in the presence of a setter). For example, you can provide data in different formats:
public double Radians { get; set; } public double Degrees { get { return Radians * 180.0 / Math.PI; } set { Radians = value * Math.PI / 180.0; } }
You can set a breakpoint to write or read properties! Breakpoints to write or read data in the Visual Studio managed code debugger until (at least until the current version of Visual Studio 2017, version 15.7) are not supported .
You can set the presence of a property in the interface, as opposed to the field:
interface ISupportsA { int A { get; } } class Data : ISupportsA { public int A { get; set; } }
You can declare the property virtual! That is, you can redefine the behavior of a property in inherited classes. Try to do this with a field.
Properties are not worse than fields in the sense that you can make a property work like this is just a field ( public int A { get; set; }
), but you cannot make a field work as a property. That is, it is almost always better to “set out” to expose a property, rather than a field.
XML serialization and WPF-ovsky Binding
only works with properties, but not with fields. Yes, this can be considered a mistake in the framework, but in fact it is.
But aren't the properties in the language superfluous? It seems that instead of a property, you can simply define two functions:
class Data { private int a; public int GetA() { return a; } public int SetA(int a) { this.a = a; } }
The answer is that.
First, one property instead of two functions is a logical group. In a good language, you say what you think. In fact, you provide the user with a “variable” A
with additional, often invisible semantics from the outside. It means that it should look like one variable, so that users of the class think in the same terms as you.
Secondly, it is the readability of the text. Compare the code with the properties:
player.car.speed++;
and without them:
getPlayer().getCar().setSpeed(getPlayer().getCar().getSpeed()+1);
What is easier to perceive?
In fairness, you need to note the disadvantages of the properties compared to the fields.
Properties cannot be used as out
/ ref
parameter, fields are possible.
Access to the fields is very fast, but access to the properties can be slow if the code inside the getter / setter is slow. However, a slow setter or (even worse) getter is considered a bad practice, it is recommended to avoid them, so as not to destroy the mental model “variable with a small addition”.
Access to a property can throw an exception or hang, while simpler fields behave extremely simply. Of course, a correctly written property will not hang, and I would recommend throwing out exceptions only in cases when a class user violated a contract for access to a field.
Another subtle difference between the property and the field is that the getter returns you a copy of the value, while working with the field you access the variable directly. When working with fields of reference types (that is, the type of which is a class), there is no practical difference, since working with an object from a copy of a link does not differ from working from the original link. There is a difference, however, when the field is a variable structure (although, in themselves, variable structures are a bad idea ). An example of a case where this is important is in the code snippet below.
It is often believed that you can first declare the data as a field, and then, if necessary, “turn” it into a property. This is only partly true : in this case, you lose binary compatibility. The code that your class used must be recompiled, since at the level of the compiled code, accessing the field and the property is not the same thing. In addition, the meaning of the code may change, leading to subtle errors. Example from the article on the link above:
using System; struct MutableStruct { public int Value { get; set; } public void SetValue(int newValue) { Value = newValue; } } class MutableStructHolder { public MutableStruct Field; public MutableStruct Property { get; set; } } class Test { static void Main(string[] args) { MutableStructHolder holder = new MutableStructHolder(); // Меняет значение holder.Field holder.Field.SetValue(10); // Получает *копию* holder.Property и изменяет её holder.Property.SetValue(10); Console.WriteLine(holder.Field.Value); // 10 Console.WriteLine(holder.Property.Value); // 0 } }
By the way, according to Wikipedia , the getter and setter correctly name the accessor and mutator, respectively. Did you know about this? [Although MSDN simply writes “ access methods .”]
Ещё одно тонкое отличие свойства от поля состоит в том, что геттер возвращает вам копию значения, в то время как при работе со свойством вы получаете доступ непосредственно к переменной.
typo. - sp7I think that there are quite a lot of use-cases in which it is useful to make a field. I will try to give you one example explaining the motivation for using a property instead of a field.
Imagine that you are developing a class library. And they implemented the class something like this:
class SuperClass { public int a; // То есть, решили, что поля достаточно. }
Your library is used by other developers (that is, clients with respect to your code). And it turns out that you want to add some logic for reading or writing a
(for example, reading a value from a config). The field here you will not manage - we do property:
class SuperClass { public int a { get { /*какая-то логика*/ } set { /*какая-то логика*/ } } }
You put the library to customers and op-pa ... Their code no longer works with yours. They can not just put the update in the form of your library, they will have to rebuild their applications, because the a field is gone. There is a property, but not a field - the external interface of the class has changed.
The code is constantly changing, everywhere there is a potential for new logic. The inconvenience described would not have happened if you immediately declared the property.
The general meaning is as follows: use properties even when it is just writing and reading from a field, then the external interface of the class will not change, even if you change the logic of working with this field.
Using a property instead of a field is an implementation of the principle of encapsulation - one of the principles of object-oriented programming.
{ get; set; }
{ get; set; }
{ get; set; }
? - Pavel Mayorov{ get; set; }
{ get; set; }
{ get; set; }
can be seen in the DTO, and the DTO is not a class in understanding the OOP. In addition, it is believed that the construction { get; set; }
{ get; set; }
{ get; set; }
breaks encapsulation as well as an open property. - Pavel MayorovThere are a lot of advantages.
But the one that benefits at the right moment is important.
This thing has benefited me.
There was a class, well, let's say with A. This class was used from a heap of places. Do not even know from what. And you need to update now, after 15 minutes. The search for use shows 1100 positions, and you only need to change where we write something to it.
Make public int A;
->
public int A {get; private set;}
And any assignment will drop a list of errors.
In addition to the detailed answer @VladD It is still convenient to initialize:
class Filter { public int ID { get; set;} public string Name { get; set;} } Filter filter = new Filter { ID = 15, Name = "Vasya" };
Thank you for your interest in this issue. Since he collected a large number of low-quality and spam responses, which had to be deleted, now it’s necessary to have 10 reputation points on the site (the bonus for account association is not counted ).
Maybe you want to answer one of the unanswered questions ?
Source: https://ru.stackoverflow.com/questions/548126/
All Articles