0
votes

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.

2
The point is, a constructor should be called in any case. if you really want to use the object initialization syntax, you can actually create a new product with this meaningless syntax new Product("West Side Story", 9.99m) { Name="West Side Story", Price = 9.99m } If you remove both constructors then the compiler builds the empty one for you, but if you remove the explicitly declared one then the sample code fails because the only constructor available requires two parameters.Steve

2 Answers

2
votes

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.

-2
votes

Instead of using private field in class & then in a property get you return the private field as is:

private int age;

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

With auto implantation the private int gets created behind the scenes.

Syntax for auto implemented property:

public int age {get; set;}