Инициализаторы объектов и Конструкторы - PullRequest
2 голосов
/ 01 июля 2010

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

Базовый класс ..

public class TestClass
{
    public string FirstName{get; set;}

    public TestClass(){
       NewClass nc = NewClass(FirstName);
    }

}

Клиентский класс

public class ClientClass
{
   public ClientClass(){
      TestClass tc = new TestClass{ FirstName="Jimmy"};
   }
}

Ответы [ 4 ]

10 голосов
/ 01 июля 2010

Инициализаторы объектов действительно синтаксически-сахарные.Дано:

var person = new Person() { Name = "Matt" };

Компилятор изменит это на:

Person person = new Person();
person.Name = "Matt";

(ну, фактически его вариант IL)

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

public TestClass(string firstName) { }
1 голос
/ 01 июля 2010
TestClass tc = new TestClass { FirstName = "Jimmy" };

является синтаксическим сахаром для

TestClass tc = new TestClass();

tc.FirstName = "Jimmy";

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

Инварианты объекта должны быть установлены конструктором и не должны нарушаться в течение срока службы объекта (или более практичные нарушения инварианта должны быть кратковременными и невидимыми для внешнего мира) Поэтому вам действительно следует передать имя в качестве параметра конструктора, если это важно для установления инвариантов объекта.

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

0 голосов
/ 01 июля 2010

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

public TestClass(string firstName){
   FirstName = firstName;
   NewClass nc = NewClass(FirstName);
}
0 голосов
/ 01 июля 2010

Нет, ты не делаешь ничего плохого. Вот как работают инициализаторы объектов. Сначала они вызывают конструктор, чтобы получить ссылку на объект, и только после того, как устанавливают свойства. Это просто синтаксический сахар.

...