В чем разница между ними и когда вы использовали бы «инициализатор объекта» вместо «конструктора» и наоборот? Я работаю с C #, если это важно. Кроме того, специфичен ли метод инициализатора объекта для C # или .NET?
В чем разница между инициализатором объекта и конструктором?
Ответы (7)
Инициализаторы объектов были добавлены в 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;
Однако в многопоточных средах атомарность инициализатора объекта может быть полезной, поскольку она предотвращает переход объекта в не полностью инициализированное состояние (см. этот ответ для более подробной информации) - он либо равен нулю, либо инициализирован, как вы и планировали.
Кроме того, инициализаторы объектов легче читать (особенно, когда вы устанавливаете несколько значений), поэтому они дают вам такое же преимущество, как и многие перегрузки в конструкторе, без необходимости иметь много перегрузок, усложняющих 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;
Теперь это облегчает поведение, подобное this. Важно знать, как работают инициализаторы объектов.
Если у вас есть свойства, которые ДОЛЖНЫ быть установлены для вашего объекта, чтобы он работал должным образом, один из способов - предоставить только один конструктор, который требует этих обязательных свойств в качестве параметров.
В этом случае вы не можете создать свой объект без указания этих обязательных свойств. Нечто подобное не может быть реализовано инициализаторами объекта.
Инициализаторы объектов - это просто «удобство синтаксиса» для сокращения начальных назначений. Красиво, но не очень функционально.
Марк
FileStream
.
- person DavidRR; 17.01.2018
Конструктор - это метод (возможно), принимающий параметры и возвращающий новый экземпляр класса. Он может содержать логику инициализации. Ниже вы можете увидеть пример конструктора.
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) }
Как видите, инициализатор объекта позволяет вам указывать значения для общедоступных полей и общедоступных (устанавливаемых) свойств одновременно с выполнением построения, и это особенно полезно, когда конструктор не предоставляет никакой перегрузки, инициализирующей определенные поля. Однако помните, что инициализаторы объектов - это просто синтаксический сахар, и после компиляции они не будут отличаться от последовательности присваиваний.
Инициализаторы объектов особенно полезны в выражениях запросов LINQ. В выражениях запросов часто используются анонимные типы, которые можно инициализировать только с помощью инициализатора объекта, как показано в примере кода ниже:
var orderLineReceiver = new { ReceiverName = "Name Surname", ReceiverAddress = "Some address" };
Подробнее об этом - Инициализаторы объектов и коллекций
Инициализаторы объектов могут быть полезны для инициализации небольшой коллекции, которую можно использовать для целей тестирования на начальном этапе создания программы. Пример кода ниже:
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() {}