присваивать значение переменной только для чтения в приватном методе, вызываемом только конструкторами - PullRequest
16 голосов
/ 27 июля 2011

C # компилятор выдал мне следующую ошибку

CS0191: Поле, доступное только для чтения, не может быть назначено (кроме как в конструкторе или инициализаторе переменной)

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

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

Ответы [ 6 ]

22 голосов
/ 22 августа 2012

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

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";
    }
}
4 голосов
/ 28 июля 2011

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

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

    private Bar InitializeBar()
    {
        // Add whatever logic you need to obtain a Foo instance.
        return new Bar();
    }
}
4 голосов
/ 27 июля 2011

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

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

public StuffClass(string a, char b)
   : this(a, b, 2) 
{}
1 голос
/ 27 июля 2011

Элементы 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 class», посколькукомпилятор не позволит вам присвоить const классам.

0 голосов
/ 14 декабря 2018

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

class Foo
{
    // public readonly MyInt = 30;
    public int MyInt { get; private set; } = 30;
}
0 голосов
/ 27 июля 2011

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

Согласно MSDN

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

...