DEV Community

loading...

Say NO to public variables! (c#)

zainjer profile image Areeb Updated on ・5 min read

What are Properties in C# and, how to use them?

Dear Reader,

While writing software, I follow a simple rule.

#1: There should be NO public variables in a class. Only private ones are allowed.

But Why do I follow that rule?

Please bear with me for a minute while I explain...

Okay, let's start by assuming (for now) that you are following this rule, and you do not use any public variables/fields in your classes.

But now, immediately afterwards, you will face an obvious problem...

How to access or manipulate an object’s fields from outside its class? Or
How will you read the members of a class from anywhere else other than itself?

Use Methods!

Java does it and almost every other OOP language encourages it!

For example, we have a field ‘score’ in a class Player:

public class Player {
     private float score;
}
Enter fullscreen mode Exit fullscreen mode

Since it is private, only the ‘Player’ class can manipulate it. But what if you wanted to access it from an outside class?

You have to write Get and Set methods like this...

public class Player {
     private float score;
     public void SetScore(float value){
         score = value;
     }
     public float GetScore(){
         return score;
     }
}
Enter fullscreen mode Exit fullscreen mode

But Why?

A sensible question would be, why should we go through all the trouble of writing accessor and mutator (Getter & Setter) methods like these?
Why not just make our fields ‘public’ and access them directly?

The answer to that is in Better Control over information.

Or in OOP terms, It allows a combination of powerful encapsulation and abstraction.

For example, you want to access the ‘score’ field from some outside class (such as HighScoreManager), but you don’t want any outside class to modify its value because you are calculating the score based on some behavior internally.
What will you do? How will you prevent some outside class to modify its value?

If the ‘score’ field is public, any other object can easily access it but also modify its value.

This is why having Getter and Setter methods can help you!
If you don’t others to manipulate a field’s value, Only write its Getter and don’t write its Setter method.

public class Player {
     private float score;

     public float GetScore(){
         return score;
     }
}
Enter fullscreen mode Exit fullscreen mode

The other feature you will obtain from using Getter Setters is that you can Observe and prep the values before they are accessed or mutated.

For example, you are keeping track of the score in the ‘float’ type with 5 decimal points precision, but the outside classes require a rounded-off value You can simply prep the value before sending it off~

public class Player {
     private float score;
     public float GetScore(){
         float value = (float)Math.Round(score,2);
        return value;
    }
}
Enter fullscreen mode Exit fullscreen mode

Similarly, you might want to do a certain action, every time a field is mutated or modified by some outside class.

public void SetScore(float value){
        UpdateStats();            
        score = value;
    }
Enter fullscreen mode Exit fullscreen mode

Here I am calling a method every time an outside class modifies the ‘score’ field.

Alright, now we can grasp why...
  • Getters & Setters are important.
  • Why we should always make our fields private. And use Getter Setters to expose them to the outside world.
  • How we can prevent others from modifying our fields by only giving them accessors (Getter methods) and no mutators (Setter methods).

Now let's talk about Properties

Assuming that you have multiple fields in a single class, wouldn’t it mean that you will have to write a lot of boilerplate code for every field you want to expose?

For example, if you have 5 fields, and you need to access at least 3 of them from outside that class, the overall footprint of that class will grow linearly as well.

For example:

public class Player {
    private float score;
    private int id;
    private string name;
    private string[] powers;
    private Vector3 position;
    public float GetScore(){
        return score;
    }
    public void SetScore(float value){
        score = value;
    }   
    public string[] GetPowers(){
        return powers;
    }
    public void SetPowers(string[] powers){
        this.powers = powers;
    }
    public Vector3 GetPosition(){
        return position;
    }

    public void SetPosition(Vector3 position){
        this.position = position;
    }
}
Enter fullscreen mode Exit fullscreen mode

Here for each field which we needed to expose, we wrote two methods. So for 3 fields, we had to write 6 methods.

Now, most languages (including Java) are stuck with a messy solution like this, But C# provides a very elegant solution called: Properties.

Using properties is very elegant!

when compared to explicitly implementing separate Getter & Setter methods.

Here is an example of the very same code from above, but with the use of Properties.

public class Player {
    public float Score {get; set;}
    private int id;
    private string name;
    public string[] Powers {get; set;}
    public Vector3 Position {get; set;}
}
Enter fullscreen mode Exit fullscreen mode

Did you notice the difference? The overall footprint of our class is much smaller now!

In case you need a Property to only be accessed but not mutated by any outside class:

public class Player {
    public float Score {get; private set;}
    private int id;
    private string name;
    public string[] Powers {get; set;}
    public Vector3 Position {get; set;}
}
Enter fullscreen mode Exit fullscreen mode

Here I added a ‘private’ access modifier before the ‘set’.
Thus, only the Player class can mutate this property now and it’s impossible to be mutated by the outside world.

There are also a few other changes you might have noticed, The properties I needed to expose are now set to ’public’.

I have also changed their names to start with a Capital letter now, and that is because they aren’t considered to be just fields anymore! They are now considered properties.
Therefore they must follow the naming convention of Properties instead of fields.

Now assuming you might need to prep the values before accessing or mutating them, how can you do that using properties?
Here is an example:

public float Score { 
        get{
            float value = (float)Math.Round(Score,2);
            return value;
        } 
        private set{
            UpdateStats();                
            Score = value;
        }        
    }
Enter fullscreen mode Exit fullscreen mode

Here I have extended the getter & setter of the ‘Score’ property so that it preps the value before accessing or mutating it.

Another cool feature of using properties over explicit Getter Setter methods is that you can assign values to properties just like a field. For example instead of using methods like this:-

public void MyMethod(){
Player obj = new Player();  

      //Getting the value
      float myScore = obj.GetScore();

      //Setting the value
      obj.SetScore(10);
    }
Enter fullscreen mode Exit fullscreen mode

This is an elegant solution:-

public void MyMethod(){
        Player obj = new Player();

        //Getting the value
        float myScore = obj.Score;

        //Setting the value
        obj.Score = 10;
    }
Enter fullscreen mode Exit fullscreen mode

Just like how we assign or extract values from a variable or field!


This is my first article on this platform! I will greatly appreciate your feedback & criticism. 😁

Reach me out at @Zainjer

Discussion (0)

Forem Open with the Forem app