Сообщение об ошибке C # «Свойство не может быть назначено - оно только для чтения». - PullRequest
0 голосов
/ 01 ноября 2018

Свойства только для чтения могут быть назначены в конструкторе. Но когда я пытаюсь явным образом реализовать метод get, компилятор показывает ошибку (свойство не может быть назначено - оно доступно только для чтения.) Могу ли я реализовать getter или оно должно быть без реализации?

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;
        }
    }
}

Ответы [ 3 ]

0 голосов
/ 01 ноября 2018

Вы ссылаетесь на свойство с полем readonly.

Это именно то, что компилятор также генерирует из C # 6 и выше при использовании автоматически реализуемого свойства со значением по умолчанию:

int MyProperty { get; } = -1;

Это будет переведено на следующее:

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

Теперь компилятор заменяет каждый вызов вашего свойства на вспомогательное поле. Однако это работает только для авто-свойств, для которых не определено тело. В вашем случае у вас уже есть такой, поэтому компилятор не может заменить его. Поскольку само свойство - это не что иное, как метод get и set, то, что вы хотите сделать, это следующее, что очевидно бессмысленно:

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

Причина, по которой это работает для автоматического свойства, заключается в том, что компилятор знает, как заменить вызов свойства. Однако предположим, что ваш собственный получатель был более сложным:

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

Теперь компилятор не может заменить вызов свойства.

Таким образом, единственный способ получить собственную реализацию get вместе со свойством, предназначенным только для get, - это использовать поле поддержки:

this._myProperty = 1;
0 голосов
/ 01 ноября 2018

Ваш класс можно переписать так:

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

    public PersonalIncome(decimal paymentRate)
    {
        AnualRate = paymentRate > 300 ? paymentRate : 40_000;
    }
}
0 голосов
/ 01 ноября 2018

Вы можете реализовать метод получения, но тогда вы можете назначить значения только непосредственно для вспомогательного поля:

_anualRate = rate; 

Как только вы решите не использовать удобство автоматической собственности, вам придется все делать самостоятельно.

...