120

In a .NET application when should I use "ReadOnly" properties and when should I use just "Get". What is the difference between these two.

private readonly double Fuel= 0;

public double FuelConsumption
{
    get
    {
        return Fuel;
    }
}        

or

private double Fuel= 0;

public double FuelConsumption
{
     get
     {
          return Fuel;
     }
}
Ali Caglayan
  • 288
  • 1
  • 2
  • 15
Ram
  • 11,404
  • 15
  • 62
  • 93

5 Answers5

143

Creating a property with only a getter makes your property read-only for any code that is outside the class.

You can however change the value using methods provided by your class :

public class FuelConsumption {
    private double fuel;
    public double Fuel
    {
        get { return this.fuel; }
    }
    public void FillFuelTank(double amount)
    {
        this.fuel += amount;
    }
}

public static void Main()
{
    FuelConsumption f = new FuelConsumption();

    double a;
    a = f.Fuel; // Will work
    f.Fuel = a; // Does not compile

    f.FillFuelTank(10); // Value is changed from the method's code
}

Setting the private field of your class as readonly allows you to set the field value only in the constructor of the class (using an inline assignment or a defined constructor method). You will not be able to change it later.

public class ReadOnlyFields {
    private readonly double a = 2.0;
    private readonly double b;

    public ReadOnlyFields()
    {
        this.b = 4.0;
    }
}

readonly class fields are often used for variables that are initialized during class construction, and will never be changed later on.

In short, if you need to ensure your property value will never be changed from the outside, but you need to be able to change it from inside your class code, use a "Get-only" property.

If you need to store a value which will never change once its initial value has been set, use a readonly field.

Thibault Falise
  • 5,795
  • 2
  • 29
  • 32
  • 19
    + 1 for code example. But need to make it clear that "Get-Only" properties can only be modified by the class methods when they are wrapped up on class fields. They can not be modified directly even by the class methods, if the setter is not there. And trying to do so would result in a compiler error. – Devraj Gadhavi Mar 25 '13 at 07:47
  • 1
    @DevrajGadhavi Except for Constructors. With `public double Fuel { get; } = 42;` the following compiles: `public FuelConsumption() { Fuel +=10; }`. – Agent49 Oct 14 '20 at 09:58
  • 1
    Readonly values can be assigned to multiple times in the constructor, so your last sentence is not correct. – duesterdust Dec 31 '20 at 15:31
  • 1
    @duesterdust Thanks for the comment, I edited my answer to make it more clear – Thibault Falise May 04 '21 at 07:21
21

As of 2015's C# 6 you can declare and initialise a read-only auto-property in one line:

double FuelConsumption { get; } = 2;

You can set the value from the constructor but not other methods.

Colonel Panic
  • 132,665
  • 89
  • 401
  • 465
8

A property that has only a getter is said to be readonly. Cause no setter is provided, to change the value of the property (from outside).

C# has has a keyword readonly, that can be used on fields (not properties). A field that is marked as "readonly", can only be set once during the construction of an object (in the constructor).

private string _name = "Foo"; // field for property Name;
private bool _enabled = false; // field for property Enabled;

public string Name{ // This is a readonly property.
  get {
    return _name;  
  }
}

public bool Enabled{ // This is a read- and writeable property.
  get{
    return _enabled;
  }
  set{
    _enabled = value;
  }
} 
Jehof
  • 34,674
  • 10
  • 123
  • 155
2

readonly properties are used to create a fail-safe code.

I really like the Encapsulation posts series of Mark Seemann about properties and backing fields: Poka-yoke Design: From Smell to Fragrance

Taken from Mark's example:

public class Fragrance : IFragrance
{
    private readonly string name;
 
    public Fragrance(string name)
    {
        if (name == null)
        {
            throw new ArgumentNullException("name");
        }
 
        this.name = name;
    }
 
    public string Spread()
    {
        return this.name;
    }
}

in this example you use the readonly name field to make sure the class invariant is always valid. in this case the class composer wanted to make sure the name field is set only once (immutable) and is always present.

KyleMit
  • 30,350
  • 66
  • 462
  • 664
danfromisrael
  • 2,982
  • 3
  • 30
  • 40
-1

Methods suggest something has to happen to return the value, properties suggest that the value is already there. This is a rule of thumb, sometimes you might want a property that does a little work (i.e. Count), but generally it's a useful way to decide.

Neil Barnwell
  • 41,080
  • 29
  • 148
  • 220