2010-02-03 2 views
2

У меня есть два частных списка, которые необходимо инициализировать при создании объекта. Второй список зависит от первого. Могу ли я сделать это следующим образом:Инициализация частных членов C#

public class MyClass 
    { 
     private List<T> myList = new List<T>(); 
     private ReadOnlyCollection<T> myReadOnlyList = myList.AsReadOnly; 

     ... 
    } 

Второй список - это только обертка только для чтения.

Могу ли я ожидать, что C# будет выполнять эти две строки в этом порядке каждый раз, когда он будет запущен?

Или я должен помещать эти инициализации в конструктор?

Редактировать:
Извините за глупый вопрос. Я попробовал и компилятор говорит:

Error 1 A field initializer cannot reference the 
      non-static field, method, or property... 
+0

Что касается вашего редактирования, см. Мой ответ ниже: http://stackoverflow.com/questions/2194531/initializing-private-members-c/2194559#2194559. – jason

ответ

11

No. Если вы хотите инициализировать переменную на основе отдельной переменной в классе, вы должны сделать это в конструкторе:

public class MyClass 
{ 
    private List<T> myList = new List<T>(); 
    private ReadOnlyCollection<T> myReadOnlyList; 
    public MyClass() 
    { 
     myReadOnlyList = myList.AsReadOnly; 
    } 

} 

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

+1

Почему downvotes? Мне очень любопытно ... –

+0

После 11 месяцев членства вы должны быть хорошо знакомы с тихими приводами с помощью downvoters здесь;) –

+0

@Mehrdad: Да, но мне всегда любопытно, почему люди случайно опрокидываются - так что я обычно спрашивайте. Иногда я получаю ответ;) [Лично мне нравится, когда я спускаюсь с разумом, потому что это обычно возможность обучения.] –

1

Да, вы должны поместить инициализацию myReadOnlyList в конструктор, но для согласованности моя рекомендация помещается как в конструктор.

4

Могу ли я ожидать, что C# выполнит эти две строки в этом порядке каждый раз, когда он будет запущен?

Да, инициализаторы переменной экземпляра, когда они законны (см. Ниже), выполняются в том порядке, в котором они отображаются. Я отсылаю вас к разделу §10.11.2 спецификации:

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

Однако инициализатор поля не может ссылаться на нестатическое поле, как вы это делали. Ваш код не является законным. Это §10.5.5.2 спецификации:

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

Что касается вашего второго вопроса:

Или я должен поставить эту инициализацию в конструкторе?

Согласно вышеизложенному, у вас нет выбора. Как минимум, вы должны поместить инициализацию myReadOnlyList в конструктор, поскольку это относится к полю экземпляра myList.Для ясности я бы поставил оба в конструкторе.

Последнее примечание, отдельный выпуск. Даже следующее не законно:

public class MyClass { 
    private List<T> myList;public class MyClass 
    private ReadOnlyCollection<T> myReadOnlyList; 
    public MyClass() { 
     myList = new List<T>(); 
     myReadOnlyList = myList.AsReadOnly; 

} 

Это потому, что вы не объявили MyClass как общий класс. Заменить public class MyClass на public class MyClass<T>.

+0

«Да, инициализаторы переменных экземпляра, когда они законны (см. Ниже), выполняются в том порядке, в котором они появляются «. - примечание стороны: порядок оценки инициализаторов в разных «частях» частичного класса не определен. –

Смежные вопросы