Pavel
Pavel

Reputation: 97

C# error message "Property can not be assigned to -- it is read only."

Read only properties can be assigned in a constructor. But when I try to explicitly implement get method, compiler shows an error (Property cannot be assigned to -- it is read only.) Can I implement getter or it's supposed to be without implementation?

public class PersonalIncome 
{
    private decimal _anualRate;
    public decimal AnualRate
    {
        get { return _anualRate != 0 ? _anualRate : 40_000;  }
    }

    public PersonalIncome(decimal paymentRate)
    {
        switch (paymentRate)
        {
            case var rate when (rate > 300):
                AnualRate = rate; // **Property can not be assigned to -- it is read only.**
                break;
            default:
              break;
        }
    }
}

Upvotes: 2

Views: 5978

Answers (3)

MakePeaceGreatAgain
MakePeaceGreatAgain

Reputation: 37000

You refer to a property with a readonly backing-field.

That´s exactly what the compiler also generates from C#6 upwards when using an auto-implemented property with a default-value:

int MyProperty { get; } = -1;

This will be translated to the following:

readonly int _myProperty = -1;
int MyProperty { get { return this._myProperty; } }

Now the compiler replaces every call to your property by the backing-field. However this only works for auto-properties that do not have a body defined. In your case you already have one, which is why the compiler can´t replace that one. As a property itself is nothing but a get- and a set-method, what you want to do is the following, which is obvious non-sense:

int get_MyProperty() { return this._MyProperty; }
...
this.get_MyProperty() = 1;

The reason this works for an auto-property is that the compiler knows how to replace the call to the property. However suppose your own getter was more complex:

get
{
    DoSomething();
    return this._myProperty + 5;
}

Now the compiler can´t replace the call to the property.

So the only way to have your own get-implementation tigether with a property which is get-only, is to use the backing-field:

this._myProperty = 1;

Upvotes: 0

Rui Jarimba
Rui Jarimba

Reputation: 17994

Your class could be rewritten like this:

public class PersonalIncome
{
    public decimal AnualRate { get; private set; }

    public PersonalIncome(decimal paymentRate)
    {
        AnualRate = paymentRate > 300 ? paymentRate : 40_000;
    }
}

Upvotes: 1

adjan
adjan

Reputation: 13652

You can implement the getter, but then you can only assign values to the backing field directly:

_anualRate = rate; 

Once you decide against using the convenience of the auto-property, you have to do everything by yourself.

Upvotes: 2

Related Questions