tags:

views:

302

answers:

7

There are situations where I declare member variables at the top of my class and then also declare a property to access or set that member variable, but I ask myself if the property is necessary if it variable is only going to be accessed and set from within the class and no where else, so what is the advantage of using a property to access and set a member variable instead of just doing it directly to the member variable itself. Here is an example:

public class Car
{

    int speed; //Is this sufficient enough if Car will only set and get it.

    public Car(int initialSpeed)
    {
        speed = initialSpeed;
    }

    //Is this actually necessary, is it only for setting and getting the member
        //variable or does it add some benefit to it, such as caching and if so,
        //how does caching work with properties.
    public int Speed 
    {
        get{return speed;}
        set{speed = value;}
    }

        //Which is better?
        public void MultiplySpeed(int multiply)
        {
            speed = speed * multiply; //Line 1
            this.Speed = this.Speed * multiply; //Line 2

            //Change speed value many times
            speed = speed + speed + speed;
            speed = speed * speed;
            speed = speed / 3;
            speed = speed - 4;

        }
}

In the above, if I don't have the property Speed to set and get the variable speed, and I decide to change int speed to int spd, I will have to change speed to spd everywhere it is used, however, if I use a property such as Speed to set and get speed, I will just have to change speed to spd in the get and set of the property, so in my MutilplySpeed method, stuff like above this.Speed = this.Speed + this.Speed + this.Speed will not break.

A: 

One thing you forgot to mention, properties will help you out when you extend your class. If your class is properly designed your variables inside the base class should be private. Without the actual properties public properties that is. You would have no way to access these private variables from within your extended class. We are talking public vs private and I am not including protected for a reason :).

Just some notes worth mentioning:

  • properties aide when a class is extended
  • properties to me make the code a bit more readable (in addition this.privateVariable verson PublicPropertyVariableName)
  • properties can ensure readonly, private sets, public gets etc (much more readable to other programmers). Consider a case where an IDentifier needs a public get but a private set
  • Personally to me too many gets / sets seems to complicate code, makes code less readable, too much extra unnecessary syntax
  • inheritance / extending to an extended class does not allow you to inherit private variables, properties are the answer. (again no mention of protected here, that is a different story)
  • To me even if the class has a private variable, my class methods still use the property to access or use that private variable
  • Don't forget about validation, it makes it much easier to validate especially readability wise.

These are just some common things (my 2 cents though on most of them).

JonH
So I take it from your answer that by making the variables private and using properties to set and get them, I am taking advantage of encapsulation?
Xaisoft
You could do that with protected variables as well.
cyberconte
+1  A: 

Things like validation can be covered at one place. The member is encapsulated, and you want have to worry about validation and other things from the rest of your class.

In your current scenario it doesn't really make a difference, but when you need to change the variable or need to add behavior, it's easier when you use properties, because you only have one place where you need to change it.

Ikke
+7  A: 

If the variable is private , I will often not create a property for it. If it is, in any way, exposed outside the type, I always expose it through a property for different reasons:

  • It may not be necessary today, but if it becomes necessary later it's a breaking change
  • Databinding works only on properties, not on fields (I think, not a big databinding user)
  • It allows to insert validations, logging, breakpoints when accessing the value

Also, if the field is exposed through a property, I always access it through the property, even within the class.

Update
In response to your updated code samples: there are a number of things to consider around the code design here.

  • Readability vs. Speed
  • "Atomicity"
  • Other side effects

One typical piece of advice (that I find very good) is "write for clarity, test for performance". That means that when you write your code, your first concern should be wheter it is clear what the code does when looking at it. This is often (but not always) more important than the raw speed of the code. Write speed optimizations when you have established where you gain it. Accessing a property will be a tad slower than reading the field directly, but in most cases, the difference will be neglectible (if at all measurable).

Atomicity may be an issue. Given your code sample, we have the field speed, that is publicly exposed through the property Speed. If the method MultiplySpeed needs to perform several updates to the value, those intermediate values will be available through the Speed property at different times while the calculation is ongoing. This is true regardless of whether you update the field directly or through the property. In cases like this it is perhaps better to first put the value into a local variable, use that for the calculations and assign the value of that variable back to the property when done.

Lastly, other side effects. It could be that changing the value of Speed should raise an event (such as SpeedChanged). In cases like that, it is also probably a good idea not to make the update until the calculation is done.

I like to think about the property as a contract and the field as implementation. Anybody (except for the core of my type) that needs the value should use the contract. Relying on the implementation should be done only if there are good reasons to bypass the contract.

And yes, if you encapsulate the access to the field in the property, naturally changing the name of the field will require less updates (and perhaps also the name of the field becomes less important).

I hope that makes sense, and is not too much off topic ;)

Fredrik Mörk
Properties are also accessible/settable via reflection
Rob Allen
I agree with using the property even in the class, even in the constructor. It's nice to know your validation logic is *always* being called.
C. Ross
+1 for using a field through a property even from inside, because it avoids nasty "setter-doesnt-run-when-it-should" bugs.
OregonGhost
@Rob: fields are also acessible/settable via reflection (`Type.GetFields`, `FieldInfo.GetValue` and `FieldInfo.SetValue`)
Fredrik Mörk
Thanks for the info. I have a question. Regarding your first bullet point: Are you saying that if I change the variable speed to spd, I will have to go through all the code and change everywhere I use to variable speed and change it to spd, but if I use a property such as Speed, I will just need to change speed to spd in the get and set? Did I understand that correctly?
Xaisoft
@Xaisoft: I think you got it right (given that I got your text right).
Fredrik Mörk
I'll update my code so you can see what I meant. Then you can let me know if I am correct.
Xaisoft
I updated it with an example of changing the variable speed many times in MultiplySpeed. If the variable speed is changed to spd, my code breaks, but if I set the values through the a property, it does not break. All I have to do is change the name of the variable in the properties set and get method, however, if I decide to change the name of my property, I am pretty much in the same boat, so I guess it is important to choose property names carefully.
Xaisoft
@Fredrik Mörk - Thanks for setting me straight there. I've only accessed via properties since my members are private...
Rob Allen
@Xaisoft: I updated my answer.
Fredrik Mörk
@Fredrik Mörk, You meant atomicity ...I think.
Vulcan Eager
@Agnel: yes you are correct; thanks for pointing it out - I will update the text.
Fredrik Mörk
+1  A: 

it does not add caching but it does allow a consistent interface.

imagine you had to ammend speed by adding a constant to it in future. using the member variable would be difficult where as the property allows this manipulation.

Also internally in the class you should again access the property for consistency (imagine the above scenario where you had a class that accessed the member variable direct).

Pharabus
+1  A: 

The only genuine reason I know of is if the field is being accessed from outside of the assembly. In that case, should you want to add light functionality to that field (maybe set a Dirty flag or validate a change) you have to change it to a property which changes the way it is viewed by the calling assembly, which will also need rebuilding. In very rare cases, you might find that you don't have control over that assembly, then you have a problem.

Don't let the OO zealots tell you that it's philsophically wrong to use public fields, although I might agree that auto-properties make the argument somewhat moot.

pdr
"Don't let the OO zealots tell you that it's philsophically wrong to use public fields, although I might agree that auto-properties make the argument somewhat moot." I'm no OO zealots but that is bad practice. All member variables should be private.
JonH
I appreciate the different points of view.
Xaisoft
Why, JonH? Don't get me wrong, I used to think the same; I still do it out of habit if I'm honest. But challenged to explain why, I don't have a better answer than the one I've just given.
pdr
@JonH - to make blanket statements like "All member variables should be private" isn't really fair to folks who work under different conditions with different goals. I find the performance reduction intollerable - but maybe I should be using C and structs instead? From your POV that should be even worse.
phkahler
@pdr, you're not likely to help anyone by using labels like "zealot" to describe folks like JonH :-) I could throw around several words with (unfair) negative connotations to say "his background is different than mine".
phkahler
+1  A: 

I agree with Frederik's answer. One thing that makes it slightly less work to follow his advice is to use automatic properties. Those are just properties that automatically generate the standard getter/setter logic. You don't get any validation, but you can always replace the automatic property with a standard one later. This replacement is not a breaking change.

Here I've replaced the Speed property in your example with an automatic property. Notice that the member variable disappears and your class must access it through the property.

public class Car
{
    public Car(int initialSpeed)
    {
        Speed = initialSpeed;
    }

    public int Speed { get; set; }

    public void MultiplySpeed(int multiply)
    {
        Speed *= multiply;
    }
}

You can also use another flavour called "get with private set". This means that the getter is public, but the setter is private. You define it like this:

    public int Speed { get; private set; }

As for your question about the this. prefix, it's usually irrelevant. The only time it matters is when you've defined a method parameter or local variable with the same name as a member variable. Then you can use this to access the member variable.

Don Kirkby
Thanks for the example.
Xaisoft
+1  A: 

The fact is, there is not a lot of difference between a publicly declared field and a public property with a private backing store if there is no extra logic. That being said, it is still considered best practice to use properties.

And before everybody jumps on me about extensibility, remember that if you do later need to add functionality, you can keep the name with the property and introduce a new name for the backing store so it's not a breaking change.

Jeff Hornby