Присваивать значение переменной readonly в частном методе, вызываемом только конструкторами

Компилятор С# дал мне следующую ошибку:

CS0191: поле readonly нельзя назначить (кроме конструктора или инициализатора переменной)

Мне нужно переместить код (в моей частной функции) в конструктор? Это звучит неловко.

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

Ответы

Ответ 1

Несмотря на то, что говорят другие сообщения, есть фактически (несколько необычный) способ сделать это и фактически назначить значение в методе:

public class Foo
{
    private readonly string _field;

    public Foo(string field)
    {
        Init(out _field, field);
    }

    private static void Init(out string assignTo, string value)
    {
        assignTo = value;
    }
}

Пример, полученный из здесь.

В качестве альтернативы вы также можете вернуть значение из частного метода и назначить его в конструкторе следующим образом:

class Foo
{
    private readonly string _field;

    public Foo()
    {
        _field = GetField();
    }

    private string GetField()
    {
        return "MyFieldInitialization";
    }
}

Ответ 2

Да. Вы пробовали цепочку конструкторов в качестве альтернативы использованию общего метода?

public StuffClass(string a, char b, int c)
{
    _a = a;
    _b = b;
    _c = c;
}

public StuffClass(string a, char b)
   : this(a, b, 2) 
{}

Ответ 3

Поле Readonly может быть назначено только конструктором. Что вы можете сделать, это инициализировать поле с помощью метода:

class Foo
{
    private readonly Bar _bar = InitializeBar();

    private Bar InitializeBar()
    {
        // Add whatever logic you need to obtain a Foo instance.
        return new Bar();
    }
}

Ответ 4

Члены readonly могут назначаться только на уровне класса или на его конструкторе. это преимущество использования ключевого слова readonly.

class Foo
{
    private readonly Foo _foo = new Foo(); // Valid

    public Foo()
    {
        _foo = new Foo(); // Valid
    }

    private void SomeMethod()
    {
        _foo = new Foo(); // Not valid
    }
}

Вы можете использовать readonly как альтернативу ключевому слову const при использовании классов "другое, что класс string", поскольку компилятор не позволит вам назначить const для классов.

Ответ 5

Если вы хотите его изменить, вы не должны читать его только в первую очередь. Как только переменная читается, вы можете изменить ее только в конструкторе или во время объявления, поскольку ошибка указывает на

Согласно MSDN

Ключевое слово readonly - это модификатор, который можно использовать в полях. Когда объявление поля содержит модификатор readonly, присваивания полям, введенным декларацией, могут выполняться только как часть объявления или в конструкторе того же класса.

Ответ 6

Вы можете буквально вставить "{get; private set;}" перед каждым знаком равенства в ваших объявлениях только для чтения, чтобы достичь почти того же (свойство теперь может быть установлено в любом месте класса, не только в конструкторе, но, по крайней мере, его нельзя изменить снаружи). учебный класс). Это строго верно для типов значений, но не для ссылочных типов, в которых readonly может иметь преимущество.

class Foo
{
    // public readonly MyInt = 30;
    public int MyInt { get; private set; } = 30;
}