Мне было интересно, что люди думают об использовании свойств в качестве инициализаторов объектов в C#. По какой-то причине кажется, что это ломает основы того, для чего используются конструкторы.
Пример...
public class Person
{
string firstName;
string lastName;
public string FirstName
{
get { return firstName; }
set { firstName = value; }
}
public string LastName
{
get { return lastName; }
set { lastName= value; }
}
}
Затем выполняем инициализацию объекта с помощью .....
Person p = new Person{ FirstName = "Joe", LastName = "Smith" };
Person p = new Person{ FirstName = "Joe" };





ИМХО это мило. Большинство объектов обновляются с помощью конструктора по умолчанию и должны иметь определенные свойства, прежде чем они будут готовы к запуску; поэтому инициализаторы объектов упрощают кодирование для большинства существующих объектов.
Здесь вы видите синтаксический сахар, предоставляемый компилятором. Под капотом он действительно делает что-то вроде:
Человек p = новый человек (FirstName = "Joe", LastName = "Smith");
Person _p = new Person();
_p.FirstName = "Joe";
_p.LastName = "Smith";
Person p = _p;
Итак, IMHO, вы на самом деле не нарушаете никаких основ конструктора, но используете хороший языковой артефакт, чтобы упростить читаемость и ремонтопригодность.
Я думаю, что в целом это полезно, особенно при использовании с автоматическими свойствами. Это может сбивать с толку, когда свойства делают больше, чем просто get / set. Надеюсь, это приведет к появлению большего количества методов и уменьшит злоупотребление свойствами.
Это также необходимо для проецируемых классов, возвращаемых из интегрированного языкового запроса (linq).
var qry = from something in listofsomething
select new {
Firstname = something.FirstName,
Lastname = something.Surname
}
Инициализаторы объектов никоим образом не заменяют конструкторы. Конструктор определяет контракт, которого вы должны придерживаться, чтобы создать экземпляр класса.
Основная мотивация для инициализаторов объектов на языке C# - поддержка Анонимные типы.
var v = new { Foo = 1, Bar = "Hi" };
Console.WriteLine(v.Bar);
Инициализаторы объектов помогают снизить сложность кодирования, поскольку вам не нужно создавать полдюжины различных конструкторов для предоставления начальных значений свойств. В моей книге все, что сокращает избыточный код, является положительным моментом.
Я считаю, что основная причина, по которой эта функция была добавлена в язык, - это поддержка анонимные типы для LINQ.
Добавляя к мыслям Несцио, я бы предложил в обзорах кода активно выслеживать дорогостоящие прозрачные операции в аксессуарах собственности, например. Круговое отключение БД.
Поскольку вы уже используете новый синтаксис C#, можно также использовать автоматические свойства, просто чтобы немного подсластить свой код:
вместо этого:
string firstName;
public string FirstName
{
get { return firstName; }
set { firstName = value; }
}
использовать это:
public string FirstName { get; set; }
Конструкторы должны иметь только аргументы требуется для создания объекта. Инициализаторы объектов - это просто удобный способ присвоить значения свойствам. Я использую инициализаторы объектов, когда могу, поскольку считаю, что это более аккуратный синтаксис.
Если вы хотите принудительно использовать конструктор, вы можете установить для вашего объекта конструктор без параметров по умолчанию как private и оставить общедоступным только некоторые принудительные конструкторы:
public class SomeObject
{
private SomeObject()
{}
public SomeObject(string someString) //enforced constructor
{}
public string MyProperty { get; set; }
}
Используя приведенное выше определение, это вызывает ошибку:
var myObject = new SomeObject { MyProperty = "foo" } //no method accepts zero arguments for constructor
Конечно, это не может быть сделано для всех случаев. Например, для сериализации требуется не частный конструктор по умолчанию.
Не ваш первоначальный вопрос, но все же ...
Объявление вашего класса может быть записано как:
public class Person
{
public string FirstName { get; set; }
public string LastName {get; set; }
}
и если бы это был мой код, у меня, вероятно, был бы объект для Name с полями First и Last.
Я, например, не доволен ими. Я не думаю, что им есть место в конструкторе, или MS должна вернуться и реорганизовать их, чтобы вы могли использовать их в частном порядке. Если я создаю объект, я хочу передать некоторые ЧАСТНЫЕ данные. Хочу один раз выставить его из внешнего мира и все. С помощью инициализаторов объектов вы позволяете изменять значения, переданные в конструктор.
Может, в будущем это изменят.
Вы, вероятно, имели в виду списки анонимных объектов (вместо «спроектированных классов»). :)