Зачем беспокоиться об инициализаторах?(.сеть) - PullRequest
5 голосов
/ 03 октября 2010

У меня есть это:

AudioPlayer player = new AudioPlayer();
player.Directory = vc.Directory;
player.StartTime = vc.StarTime;
player.EndTime = vc.EndTime;

Но я мог бы иметь это:

AudioPlayer player = new AudioPlayer
{
    Directory = vc.Directory,
    StartTime = vc.StarTime,
    EndTime = vc.EndTime
};

Если я перейду на «новый способ написания вещей», что я получу, кроме нечитаемости? Это сделает меня ближе к лямбда-функциям (=>)?

Это как-то связано с RAII ?

Сложение:

Некоторые ответили, что обычная инициализация может оставить объект в «недействительном» состоянии после, например, установки только свойства Справочника - мое наблюдение здесь заключается в том, что тот, кто проектировал объект, вероятно, проектировал его таким образом, что только значения, которые ДОЛЖНЫ действительно введенные вводятся через реальный конструктор, и все остальные могут быть позже изменены свободно.

Ответы [ 6 ]

10 голосов
/ 03 октября 2010

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

var player = new AudioPlayer
{
    Car = new Car()
    {
        WheelSize = new Inch(21),
        Driver = new Person()
        {
            Age = 53,
            Type = LicenseType.B,
            Family =
            {
                new Person("Jane"),
                new Person("Pieter"),
                new Person("Anny")
            }
        }
    }
    Directory = vc.Directory,
    StartTime = vc.StarTime,
    EndTime = vc.EndTime
};

Попробуйте сделать это по-старому.Это становится действительно уродливым.

2 голосов
/ 09 октября 2010

Инициализаторы становятся обязательными, а не просто полезными, когда имеешь дело с анонимными типами.

Например:

var x = new {Foo = "foo", Bar = "bar"};

2 голосов
/ 03 октября 2010

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

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

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

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

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

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

2 голосов
/ 03 октября 2010

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

AudioPlayer player = new AudioPlayer();
player.Directory = vc.Directory;
player.StartTime = vc.StarTime;
player.EndTime = vc.EndTime;
some.Method(player);

Или вы можете использовать инициализаторы объектов:

some.Method(
  new AudioPlayer
  {
      Directory = vc.Directory,
      StartTime = vc.StarTime,
      EndTime = vc.EndTime
  });

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

Кроме того, я думаю, что удобочитаемость (и «доступность для записи») лучше: вам не нужно повторять имя переменной бесконечно.

1 голос
/ 03 октября 2010

Вы получаете код на 21 символ меньше. Чем меньше кода, тем меньше ошибок. И чтобы получить еще больше, вы можете использовать неявный вывод типа переменной: var player = new AudioPlayer {

1 голос
/ 03 октября 2010

Я считаю, что этот синтаксис был добавлен, потому что его проще использовать с лямбда-выражением, поэтому вы можете легко сделать что-то вроде item => new Person() { Name = item.Name }.

Я не думаю, что он имеет какое-либо отношение к RAII, хотя..

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...