Search code examples
c#automatic-propertiesprivate-constructor

Do auto implemented properties use private constructors for their initialization


I was reading Jon Skeet's C# in depth and came across the explanation for auto-implemented properties in C# 3.

The code for this was:

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}
               };
    }
}

And the text that explains this is

Now the properties don’t have any code (or visible variables!) associated with them, and you’re building the hardcoded list in a very different way. With no name and price variables to access, you’re forced to use the properties everywhere in the class, improving consistency. You now have a private parameterless constructor for the sake of the new property-based initialization. (This constructor is called for each item before the properties are set.) In this example, you could’ve removed the public constructor completely, but then no outside code could’ve created other product instances.

I'm unable to wrap my head around the portion marked in bold. It says that the private constructor is there for the auto-implemented properties and is called every time before it is set. However, even when I put a console in there it did not get called. And even with the private constructors removed the code ran fine.

I know the role of private constructors in C# but I am unable to understand how it is related to auto-implemented properties if it is from the text above.


Solution

  • This piece of code is using object initializer syntax in GetSampleProducts static method. Object initializers can be used only on types with parameterless constructor, because it's all about syntactic sugar. This

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

    is really translated into this under the hood

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

    It means parameterless constructor is required for var p = new Product(); call. And it will be actually called for each item before the properties are set.

    Constructor is private, but as far as GetSampleProducts is inside Product type, it can access Product private members. If you try the same syntax outside of this class it will fail.

    So, this

    You now have a private parameterless constructor for the sake of the new property-based initialization.

    Actually means that constructor isn't used for auto-implemented properties here, it's required for property-based initialization (this term means object initializer), and if you remove it, you will get compilation errors.