- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
PropertyAdminFormModel data = new PropertyAdminFormModel
{
DateFinish = rep.DateFinish,
Name = rep.Name,
ReportingCircleId = rep.ReportingCircleId
};
if (data != null)
{
Id = reportId;
Name = data.Name;
DateFinish = data.DateFinish;
ReportingCircleId = data.ReportingCircleId;
}
Вариант: сишник старой закалки. Выделение памяти надо проверять! А не надеяться на авось и много памяти и исключения
насколько я знаю то этот синтаксис вышел вместе с C# 3.0, то ли в 2004, то ли в 2005
>с C# 3.0, то ли в 2004, то ли в 2005
Лол. Ada, Java гораздо древнее.
>Instance initializers
Java 1.1 introduced the instance initializer, which is also called the instance initialization block
Добавили вместе с inner-классами.
Но вообще идея неймспесов совершенно органичная, в ней нет какой-то особой оригинальности.
sealed что ли?
а что тогда получается?
var tempPerson = new Person();
tempPerson.Name = "a";
tempPerson.Age = 2;
person = tempPerson;
Тут инициализация person атомарна, он либо null, либо полностью инициализирован, нет никаких неопределенных состояний.
var person = new Person();
person.Name = "a";
person.Age = 2;
А тут нет - ибо нет никакого способа определить, полностью ли инициализирован person? Сколько надо ждать до его инициализации? Можно ли с ним уже работать из другого потока?
var tempPerson = new Person();
tempPerson.Name = "a";
tempPerson.Age = 2;
person = tempPerson;
Или я не понимаю c#, или вы не знаете что такое memory ordering. На c/c++ за такой код в многопоточке убивают.
>>вы не знаете что такое memory ordering
не знаю
>>На c/c++ за такой код в многопоточке убивают
ну.. компилятору ведь можно такой код генерить..
Раз вы упомянули атомарность - значит мы рассматриваем многопоточную программу.
Допустим ваш код выполняется в одном потоке, а использовать переменную в другом будут при помощи такого кода:
if (person != null) { .. делаем что-то .. }
Ваш код выделяет объект, корректно заполняет его и выкладывает ссылку в переменную person. Т.к. c# (в отличие от с/c++) при любой записи вываливает весь кеш в оперативную память, в оперативной памяти будет корректно размещен и сам объект и ссылка на него.
Но к сожалению, т.к. переменная не объявлена как volatile, второму процу никто ничего об этом не сказал, и когда он случайно (да, да, случайно) перечитает страничку кеша в которой лежит person он обрадуется и пойдет им пользоваться. При этом, с ненулевой вероятностью, забыв прочитать вторую страничку кеша, в которой собственно валялся объект...
Как результат программу разносит в клочья (в лучшем случае) или кто-то не получает зарплату (в лучшем случае вы).
> не знаю
жаль
> ну.. компилятору ведь можно такой код генерить..
Без volatile с\с++ компилятор имеет полное право сделать из вашего кода вот такой (и, что характерно, сделает!):
Person person = new Person();
person.Name = "a";
person.Age = 2;
Насчет компилятора c# не знаю, т.к. с c# не работаю.
Есть глобальная переменная (ну или член класса) Person person = null.
Есть некая функция, которая хочет поместить туда инфу о новом человеке. И если она будет выглядеть так:
person = newPerson();
person.name = "a";
person.age = 2;
То при возникшем исключении person может остаться в неопределенном состоянии.
А конструктор с {...} атомарен в том плане, что либо он создает объект, заполняет все поля и после этого происходит присваивание. Либо, если в конструкторе возникло исключение - присваивания не
происходит вообще.
Т.е. это просто синтаксический сахар, позволяющий не писать временную переменную:
Person tempPerson = new Person();
tempPerson.name = "a";
tempPerson.age = 2;
person = tempPerson;
Вот только про потоки тут упоминать не следовало.
Выхлоп monodis'а: http://pastebin.com/ZRX3mN65
Да, вы правы, он создал временную переменную и после инициализации скопировал ее в нужную.
Если бы data в коде ОП'а была бы глобальной или членом класса, или хотя бы была описана над try..catch блоком - тогда подобная конструкция безусловно необходима.
Но т.к. и в коде ОП'а и в коде uusb мы видим локальную переменную, которую до окончания инициализации никто никуда не передал, то при исполнении эти коды будут эквивалентны. Так как при возникновении исключения в конструкторе или инициализации полей не будет выполнен код, который шел после инициализации - никто не воспользуется недоделанным объектом.
насколько я знаю то этот синтаксис вышел вместе с C# 3.0, то ли в 2004, то ли в 2005