Property Vs variables

Asked

Viewed 1,530 times

29

I’ve always used properties in C# this way:

public int Numero { get; set; }

Today I asked myself, why do I use this get and set instead of a variable?

Is there a difference? I only use it that way because I learned it that way, but I don’t know why.

public int numero;

There is difference between using the properties according to the first and second form?

First form:

public int Numero { get; set; }

Second form:

private int numero;
public int Numero
{
    get
    {
        return numero;
    }
    set
    {
        numero = value;
    }
}

1 answer

25


Great to have asked. It’s never cool to go around using things without questioning. Even if you get it right it will be by coincidence.

The two property usage codes (the ones at the end of the question) are equivalent. We can say that the second will be the code actually generated when using the first. There is no reason to write the second (in this case).

The shape of the second is only useful when it escapes from this so common standard, which is only to have a private support field and the logic of assigning and accessing this field by methods accessors (yes, in fact are created internally two methods to access the private field, and they are only optimized in class internal access).

Even if you need the writing in the field to be private, you can mark the set as private in the first form.

In the past, a reason to make everything separate was when I wanted to initialize a value in the property when the object was created. The only way was to do this on the field, so I needed to unlock everything. C#6 now allows initialization in the property itself.

public int Numero { get; set; } = 5;

In C# 6 if the property has only one get with logic and not having a set can make it simpler:

public int Numero => numero;

Normally it should have a more complex logic than this, but in this particular case it is the same as:

public int Numero { get; };

I put in the Github for future reference.

This form is called Expression body and is very much like a lambda, although it is not a.

In C# 9 it is possible to use a init in place of set and allow the property to be initialized, then can no longer be changed.

Property is really necessary?

It’s actually a question of whether you really need access to the property. It is often said that internal fields should be accessed through other, more significant methods and not through accessors direct. Of course this is exaggeration in most cases. There are situations where the only thing you want is to access the property purely and simply. Then it makes sense.

Just think before if you are really doing what is necessary. If it is, the property has no problem at all, just don’t do it on automatic.

I see cases where you’ll never have public access to the property, so there’s no point in creating it. There are worse cases, the direct public access to it can cause some problem for that class.

Has frameworks that require access to be done by the properties. This is the case for the Entity Framework. It makes sense to have this requirement - I explain why below. Then you have to create.

Why not give access to the public field?

One may also question whether to create a property or simply give public access to the field. Think about it, so create a property that does the same as the access to the field directly already offers?

In general people do not know how to answer this. They do because they read somewhere that is how it should be. But no one should do anything just because of that, there must be a reason.

In other languages that do not have this property syntax it is very common to require the creation of methods getter and Setter because your code will initially offer the public field, and then later a maintenance will require access to do a little processing. Let’s say that in assigning a value to the field you need to do a validation. Or to get the value you need to do a quick calculation first. What to do? Changes the field to private, creates the two methods of get and set and have everyone who consumed their class change their codes to access the field by methods from now on. If your class is popular, it may be that thousands of programmers around the world have to do it. Unworkable, right?

C# does not suffer from this problem, because syntactically the access by the methods accessors is identical to direct field access.

Problem solved then? No. The problem of consumers in your class remains.

When the consumer compiles and has access to the field, it is an access to a variable, a memory position. Same in other languages. When you switch to a property, methods are automatically created and are available for use. Codes sources consumers of the class do not need to be touched. But they have already been compiled the other way (access to memory directly). This does not change on its own.

You solve the problem by re-compiling the consumer code of your class. In the new compilation it will be seen that it is now a property and will generate access by the auxiliary methods created by the compiler in the class that has been changed. Easy to solve.

But you can not always guarantee that a change in your class will generate a new compilation in consumer codes to meet the new API (yes, the API changes). If your class is distributed to third parties or it is used by EF, for example, you cannot control it even if you want to.

So whenever you can ensure that this compilation will be done, ie in internal projects that you have control over, or if the execution has some versioning control that won’t call the library’s "wrong" version, you can use the direct field. And that has performance advantages (whether you need this advantage or not, it’s something else).

But if you do not have control over consumption, the best thing is to ensure that the consumer code makes access through the property, so the methods are already called instead of the access being done by the variable. So when you mess with your class all the consumer codes will call the method with the new code, since creating a function/method is a form of indirect. And...

All computing problems can be solved with an extra level of indirect

Once this is done the consumer code no longer needs to worry about how access to the property is done, it calls the method and whatever is inside will be executed. If you’ve touched your class, you’ll reflect on this execution, because the Binding (linkage) of the function implementation is always dynamic (at runtime). The decision of what to call is always made at compile time (at least in static languages), so it causes the problem of different versions. You can only ensure they are compatible if they are compiled in sync.

Principle Open/Close

Has the principle Open/Close that is part of the SOLID. Some people preach that this should be strictly followed in OOP. If this is followed even then there is no reason to use properties or methods getter/Setter. It follows that either this principle is foolish or this idea of encapsulating things makes no sense.

I prefer to stick with what I always say, do what you have to do in each case. If you want to create a contract, respect the contract and do not change it, if you know that the implementation can change and can not control its effects, prepare the code to handle it well.

The use of the property makes sense when it will be virtual, a variable can never be virtual.

Now you know why to use the property and when it’s not needed.

Related:

  • Thanks @bigown.

  • I think I understand more or less, meaning then that if I am working in a class I am absolutely sure that the variables(fields) never need a processing or a validation before it is set or obtained I can create only the variable without any problem but if I do not have this certainty and maybe in the future other people will consume this class and variable and I need to do a processing or a direct validation on it is better I already create as property not to have this problem future, that’s it?

  • @Mauricioferraz is basically this. In fact even if you are sure that consumers will always be compiled again if you change your class you can also use the direct variable without going through the property. But you have to have all these certainties, if you have any chance of that not being guaranteed, you better go to the safe way and create the property. Some people prefer to follow the rule blindly and always do it. It even works, but it’s good to know that you can do it another way.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.