Используют ли автоматически реализованные свойства частные конструкторы для их инициализации

Я подробно читал C # Джона Скита и наткнулся на объяснение автоматически реализуемых свойств в C # 3.

Код для этого был:

class Product
{
    public string Name { get; private set; }
    public decimal Price { get; private set; }

    public Product(string name, decimal price)
    {
        Name = name;
        Price = price;
    }

    Product() {}

    public static List<Product> GetSampleProducts()
    {
        return new List<Product>
               {
                   new Product { Name="West Side Story", Price = 9.99m },
                   new Product { Name="Assassins", Price=14.99m },
                   new Product { Name="Frogs", Price=13.99m },
                   new Product { Name="Sweeney Todd", Price=10.99m}
               };
    }
}

И текст, объясняющий это,

Теперь со свойствами не связан какой-либо код (или видимые переменные!), И вы создаете жестко запрограммированный список совсем другим способом. При отсутствии переменных имени и цены для доступа вы вынуждены использовать свойства повсюду в классе, что улучшает согласованность. Теперь у вас есть частный конструктор без параметров для новой инициализации на основе свойств. (Этот конструктор вызывается для каждого элемента перед установкой свойств.) В этом примере вы могли бы полностью удалить общедоступный конструктор, но тогда никакой внешний код не смог бы создать другие экземпляры продукта.

Я не могу обернуть голову вокруг части, выделенной жирным шрифтом. В нем говорится, что частный конструктор существует для автоматически реализуемых свойств и вызывается каждый раз перед его установкой. Однако даже когда я вставил туда консоль, она не вызывалась. И даже после удаления частных конструкторов код работал нормально.

Я знаю роль частных конструкторов в C #, но не могу понять, как это связано с автоматически реализуемыми свойствами, если это взято из приведенного выше текста.


person thebenman    schedule 13.05.2018    source источник
comment
Дело в том, что конструктор должен вызываться в любом случае. если вы действительно хотите использовать синтаксис инициализации объекта, вы можете создать новый продукт с этим бессмысленным синтаксисом новый продукт (West Side Story, 9,99 млн) {Name = West Side Story, Цена = 9,99 млн} Если вы удалите оба конструктора, компилятор построит для вас пустой, но если вы удалите явно объявленный, тогда образец кода завершится ошибкой, потому что единственный доступный конструктор требует двух параметров.   -  person Steve    schedule 13.05.2018


Ответы (2)


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

var p = new Product { Name="West Side Story", Price = 9.99m }

действительно переводится в это под капотом

var p = new Product();
p.Name = "West Side Story";
p.Price = 9.99m;

Это означает, что для вызова var p = new Product(); требуется конструктор без параметров. И он будет фактически вызываться для каждого элемента до того, как будут установлены свойства.

Конструктор является частным, но поскольку GetSampleProducts находится внутри типа Product, он может обращаться к Product закрытым членам. Если вы попробуете использовать тот же синтаксис за пределами этого класса, это не удастся.

Итак, это

Теперь у вас есть частный конструктор без параметров для новой инициализации на основе свойств.

Фактически означает, что конструктор здесь не используется для автоматически реализуемых свойств, он требуется для инициализации на основе свойств (этот термин означает инициализатор объекта), и если вы удалите его, вы получите ошибки компиляции.

person Uladzislau    schedule 13.05.2018

Вместо использования частного поля в классе, а затем в свойстве вы возвращаете частное поле как есть:

private int age;

public int Age
{get {return age;}
 set {age = value}
}

При автоматической имплантации частный int создается за кулисами.

Синтаксис для автоматически реализованного свойства:

public int age {get; set;}
person David Edel    schedule 13.05.2018
comment
Минус, потому что это не отвечает на вопрос OP о конструкторе без параметров и его связи со свойствами. - person Uladzislau; 13.05.2018