Порядок операций с использованием синтаксиса инициализатора объекта - PullRequest
28 голосов
/ 30 января 2009

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

Например, если я сделаю это:

var s = new Person { FirstName = "Micah",
                     LastName = "Martin",
                     IsLoaded = true
                   }

будет ли каждое свойство быть установлено в том же порядке?

1 Ответ

44 голосов
/ 30 января 2009

Да.

Прошу прощения за то, что меня прервали (на самом деле мне приходится часто выполнять какую-то работу). Спецификация не явно говорит это, но это делает довольно ясным IMO в разделе 7.6.10.2:


Инициализатор объекта состоит из последовательности инициализаторов-членов, заключенных в токены {и} и разделенных запятыми.

(Обратите внимание на слово «последовательность», а не «набор». Лично я считаю, что это важно, поскольку последовательность упорядочена.)

Следующий класс представляет точку с двумя координатами:

public class Point
{
    int x, y;
    public int X { get { return x; } set { x = value; } }
    public int Y { get { return y; } set { y = value; } }
}

Экземпляр Point можно создать и инициализировать следующим образом:

Point a = new Point { X = 0, Y = 1 };

, который имеет тот же эффект, что и

Point __a = new Point();
__a.X = 0;
__a.Y = 1; 
Point a = __a;

где __a - невидимая и недоступная временная переменная в противном случае.


РЕДАКТИРОВАТЬ: Я получил ответ от Mads Torgersen, который в основном сказал, что все, что можно сделать сейчас, сохранит порядок. В будущем могут быть некоторые странности, когда порядок не сохраняется в странных случаях, когда вы делаете что-то иное , чем установка свойства / поля, но это будет зависеть от того, куда идет язык.

Стоит отметить, что на самом деле здесь происходит много шагов - есть порядок выполнения оценки аргументов (то есть биты RHS) и порядок выполнения назначений. Например, если у вас есть:

new Foo
{
    A = X,
    B = Y
}

возможны все следующие заказы при сохранении порядка фактического выполнения свойства (A и B):

  • Оценить X, присвоить A, оценить Y, присвоить B
  • Оценить X, оценить Y, присвоить A, присвоить B
  • Оценить Y, оценить X, присвоить A, присвоить B

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

Я бы также очень опасался на самом деле писать код, который зависит от этого ...

...