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


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

5 151

5 ответов:

инициализаторы объектов были чем-то добавлены в C# 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;

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

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

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

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

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

когда вы

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;

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

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

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

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

Марк

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


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) }

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