C # инициализатор вложенного объекта - PullRequest
0 голосов
/ 28 января 2019

C # 5.0 Спецификация языка 7.6.10.2 Инициализаторы объектов утверждают, что

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

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

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

using System;

namespace ObjectCollectionInitializerExample
{
    struct MemberStruct
    {
        public int field1;
        public double field2;
    }
    class ContainingClass
    {
        int field;
        MemberStruct ms;
        public int Field
        {
            get { return field; }
            set { field = value; }
        }
        public MemberStruct MS
        {
            get { return ms; }
            set { ms = value; }
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            // Nested object initializer applied to a property of value type compiles!
            ContainingClass cc = new ContainingClass { Field = 1, MS = new MemberStruct { field1 = 1, field2 = 1.2} };
            Console.ReadKey();
        }
    }
}

Я прокомментировал код, в котором предполагалось генерировать ошибку компилятора на основе спецификации.Но он успешно компилируется.Что мне здесь не хватает?

Спасибо

1 Ответ

0 голосов
/ 28 января 2019

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

Вот как будет выглядеть использование инициализатора вложенного объекта:

ContainingClass cc = new ContainingClass { Field = 1, MS = { field1 = 1, field2 = 1.2} };

Это не будет компилироваться, когда MS является типом значения (структура), но будет компилироваться, когда MS является ссылочным типом (объект).

...