Как назначить переменную-член только для чтения в инициализаторе объекта? - PullRequest
6 голосов
/ 29 февраля 2012
class foo {
    public readonly int bar;
};
foo a = new foo() { bar = 123 };

error CS0191: A readonly field cannot be assigned to (except in a constructor or a variable initializer)

Как назначить bar в инициализаторе объекта выше?

Можно ли инициализировать элементы только для чтения без необходимости писать собственный конструктор для каждого класса / структуры?

Ответы [ 6 ]

7 голосов
/ 29 февраля 2012
foo a = new foo() { bar = 123 };

преобразуется компилятором в

foo temp = new foo();
temp.bar = 123;
foo a = temp;

Как видите, присваивание bar отсутствует ни в конструкторе foo, ни в инициализаторе переменной.

Итак, ответ таков: вы не можете.

5 голосов
/ 22 января 2014

Обобщение других ответов: Сообщение об ошибке не помогает: инициализаторы объектов нельзя использовать с полями только для чтения.

Однако конструкторы с именованными аргументами могут,и синтаксис для этого очень похож. Так похоже, что вы даже можете подумать, что вы видели инициализаторы объектов C # для полей только для чтения (как я это делал) , когда вы действительно видели это:

class Foo {
    public Foo(int bar) {
        this.bar = bar;
    }
    public readonly int bar;
};

Foo a = new Foo(bar: 123);
// instead of `new Foo() { bar = 123 };`
1 голос
/ 29 февраля 2012

Вы передаете значение в конструктор:

public class foo 
{
    public readonly int _bar;

    public foo(int bar) 
    {
        _bar = bar;
    }
};


var x = new foo(12345);

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

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

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

0 голосов
/ 29 февраля 2012

Вы не можете.Что ошибка хочет сказать вам, что вы можете использовать

class foo {
    public readonly int bar = blabla;
};

Синтаксис инициализатора объекта, который вы используете, это просто синтаксический сахар для вызова конструктора и назначения членам.И это «недопустимо для элементов только для чтения.


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

0 голосов
/ 29 февраля 2012

Вы не можете. Вы должны использовать конструктор для этого. MSDN

0 голосов
/ 29 февраля 2012
class Foo {
     private int bar;

     public Foo( int bar ){
         this.bar = bar;
     }

     public int Bar {
         get { return this.bar; }
     }
}

Foo foo = new Foo( 123 );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...