Какая разница между инициализатором объекта и конструктором?

Каковы различия между ними и когда вы используете "инициализатор объектов" над "конструктором" и наоборот? Я работаю с С#, если это имеет значение. Кроме того, является ли метод инициализации объекта специфичным для С# или .NET?

Ответ 1

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

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

MyObject myObjectInstance = new MyObject(param1, param2);

В этом случае конструктор MyObject будет запущен со значениями param1 и param2. Они оба используются для создания нового MyObject в памяти. Созданный объект (который настроен с использованием этих параметров) возвращается и устанавливается в myObjectInstance.

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

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

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

MyObject myObjectInstance = new MyObject(param1, param2)
{
    MyProperty = someUsefulValue
};

Это будет вести себя так же, как если бы вы это сделали:

MyObject myObjectInstance = new MyObject(param1, param2);
myObjectInstance.MyProperty = someUsefulValue;

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

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

Ответ 2

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

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

Вы использовали бы конструктор без помощи инициализатора объекта, если конструктор достаточно задал начальное состояние объекта. Однако инициализатор объекта должен использоваться вместе с конструктором. Синтаксис требует явного или неявного использования (VB.Net и С#) конструктора для создания исходного объекта. Вы должны использовать инициализатор объекта, когда конструктор не будет достаточно инициализировать объект для вашего использования, и несколько простых полей и/или наборов свойств будут.

Ответ 3

Когда вы делаете

Person p = new Person { Name = "a", Age = 23 };

это то, что по существу делает инициализатор объекта:

Person tmp = new Person(); //creates temp object calling default constructor
tmp.Name = "a";
tmp.Age = 23;
p = tmp;

Теперь это облегчает поведение, например . Знание того, как работают инициализаторы объектов, важно.

Ответ 4

Если у вас есть свойства, которые ДОЛЖНЫ быть установлены на вашем объекте, чтобы он работал правильно, один из способов - показать только один конструктор, который требует этих обязательных свойств в качестве параметров.

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

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

Марк

Ответ 5

Конструктор - это метод (возможно), принимающий параметры и возвращающий новый экземпляр класса. Он может содержать логику инициализации. Ниже вы можете увидеть пример конструктора.


public class Foo
{
    private SomeClass s;
    public Foo(string s)
    {
       s = new SomeClass(s);
    }
}

Теперь рассмотрим следующий пример:


public class Foo
{
    public SomeClass s { get; set; }
    public Foo() {}
}

Вы можете добиться того же результата, что и в первом примере, используя инициализатор объекта, предполагая, что вы можете получить доступ к SomeClass со следующим кодом:


new Foo() { s = new SomeClass(someString) }

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

Ответ 6

Объектные инициализаторы особенно полезны в выражениях запросов LINQ. В выражениях запросов часто используются анонимные типы, которые можно инициализировать только с помощью инициализатора объекта, как показано в приведенном ниже примере кода: '

var orderLineReceiver = new { ReceiverName = "Name Surname", ReceiverAddress = "Some address" };

Подробнее об этом - Инициализаторы объектов и коллекций

Ответ 7

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

    class Program
    {
        static void Main(string[] args)
        {
            List<OrderLine> ordersLines = new List<OrderLine>()
            {
                new OrderLine {Platform = "AmazonUK", OrderId = "200-2255555-3000012", ItemTitle = "Test product 1"},
                new OrderLine {Platform = "AmazonUK", OrderId = "200-2255555-3000013", ItemTitle = "Test product 2"},
                new OrderLine {Platform  = "AmazonUK", OrderId = "200-2255555-3000013", ItemTitle = "Test product 3"}
            };
        }
    }
    class OrderLine
    {
        public string Platform { get; set; }
        public string OrderId { get; set; }
        public string ItemTitle { get; set; }
    }

Вот подвох. В приведенном выше примере кода не включен ни один конструктор, и он работает правильно, но если какой-то конструктор с параметрами будет включен в класс OrderLine в качестве примера:

public OrderLine(string platform, string orderId, string itemTitle)
{
   Platform = platform;
   OrderId = orderId;
   ItemTitle = itemTitle;
}

Компилятор покажет ошибку - Нет заданного аргумента, соответствующего необходимому формальному параметру…. Это можно исправить, включив в класс OrderLine явный конструктор по умолчанию без параметров:

public OrderLine() {}