property-based initialization.

Hi experts,

from the code below, Initializing Product looks little bit different from what I have done.
1. In GetSampleProducts(), return statement comes first.
2. Also it uses {} instead of () to initialize each product.
3. we need a private parameterless constructor Product(){}.

I guess that it's because it uses properties instead instance variable. Can anybody explain these in more detail please?

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 Stroy", 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}
            };
        }
}

Open in new window

IzzyTwinklyAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

it_saigeDeveloperCommented:
1.  To answer this question, you must understand that:
public static List<Product> GetSampleProducts()
{
	return new List<Product>
	{
		new Product {Name ="West Side Stroy", 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}
	};
}

Open in new window

Logically is the same as:
public static List<Product> GetSampleProducts()
{
	List<Product> results = new List<Product>();
	results.Add(new Product { Name = "West Side Stroy", Price = 9.99m });
	results.Add(new Product {Name = "Assassins", Price = 14.99m});
	results.Add(new Product {Name = "Frogs", Price = 13.99m});
	results.Add(new Product { Name = "Sweeney Todd", Price = 10.99m });
	return results;
}

Open in new window


2. The bracket's define a initialization process.  Think of this as the same thing as:
int a = 5;

Open in new window

The difference here is that you are initializing a reference item, so you have to tell the initializer which property[ or properties] you are declaring the value for.

3.  A parameter less constructor is needed if you plan on declaring a new instance of a class without passing parameters and have an existing constructor defined that accepts parameters.  The fact that the parameter less constructor is marked private simply means that anything outside of the Product class cannot declare a new instance without using the constructor that accepts parameters.

-saige-
it_saigeDeveloperCommented:
So lets have a little fun with your code:
using System;
using System.Collections.Generic;
using System.Linq;

namespace EE_Q28705107
{
	class Program
	{
		static void Main(string[] args)
		{
			var products = Product.GetSampleProducts();
			// I'm going to add a new Product to my products list.
			products.Add(new Product("Mad Max", 49.99m) { Quantity = 5 });
			foreach (var product in products)
				Console.WriteLine(product);

			Console.WriteLine(Product.Checkout(products));
			Console.ReadLine();
		}
	}

	class Product
	{
		public string Name { get; private set; }
		public decimal Price { get; private set; }
		public int Quantity { get; set; }
		public decimal Total { get { return Price * Quantity; } }

		public Product(string name, decimal price)
		{
			Console.WriteLine("IN CONSTRUCTOR WITH PARAMETERS");
			Name = name;
			Price = price;
		}

		Product() 
		{
			Console.WriteLine("IN PARAMETERLESS CONSTRUCTOR");
		}

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

		public static string Checkout(IEnumerable<Product> products)
		{
			return string.Format("Total cost: {0:C2}", products.Sum(x => x.Total));
		}

		public override string ToString()
		{
			return string.Format("{0} of {1} at {2:C2} = {3:C2}", Quantity, Name, Price, Total);
		}
	}
}

Open in new window

Produces the following output -Capture.JPG-saige-
IzzyTwinklyAuthor Commented:
Thanks Saige!

I am still little bit confused.
In your answer for question 3, you said, "A parameter less constructor is needed if you plan on declaring a new instance of a class without passing parameters and have an existing constructor defined that accepts parameters. "

When we do 'new Product {Name ="West Side Stroy", Price = 9.99m}', I thought that we are passing 2 parameters. But it seems that this line calls parameterless constructor, right?
hum...
Python 3 Fundamentals

This course will teach participants about installing and configuring Python, syntax, importing, statements, types, strings, booleans, files, lists, tuples, comprehensions, functions, and classes.

it_saigeDeveloperCommented:
No, you are initializing a new instance of Product and setting the Name and Price properties using the parameter less constructor.  If you look at my output, you will see that it states that the parameter less constructor is called when the GetSampleProducts() method is called.

To further drive my point home, if you were to remove the parameter less constructor then the program would not compile as the GetSampleProducts() method used it to initialize the list of sample products; e.g. -If we remove the parameter-less contructor, the compiler gives us errors.We could resolve this issue by having the GetSampleProducts() method use the constructor with parameters, e.g. -Changing the GetSampleProducts() method to use the contructor with parameters.If we now run the application you will see that the output changes; e.g. -Capture.JPG-saige-

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
it_saigeDeveloperCommented:
To further prove my point, let's say we now decide we don't want to define a constructor that accepts parameters, matter of fact, we don't want to define any constructors of any kind.  What do you think will happen now?

Well let's find out -Capture.JPGIt appears as if the compiler does not like that we are trying to use a constructor.  But remember a class (by default) does not need a constructor/destructor as an implied public, parameter-less, constructor/destructor is generated by default.  Let's test that theory by trying to just initialize our instances with a parameter-less constructor.Capture.JPGUh-oh now we got a new error.  The implied constructor is public but the accessors (the setters) for two of the properties (Name and Price) are not.  These are marked as private, this means that only a class defined method can access the properties.  So we can do one of a few things:
1,  We can make the setters public by removing the private declaration.
2.  We can create a new constructor that takes the parameters.
3.  We can create a method that allows us to set the parameters.

For the sake of simplicity, let's remove the private declaration from the property setters (I will leave you with the third option as we have already proven the second option works).
And once again, everything is right in the world -Capture.JPGNow let's run it and see what output we get -Capture.JPGAnd finally here is the updated code -
using System;
using System.Collections.Generic;
using System.Linq;

namespace EE_Q28705107
{
	class Program
	{
		static void Main(string[] args)
		{
			var products = Product.GetSampleProducts();
			// I'm going to add a new Product to my products list.
			products.Add(new Product { Name = "Mad Max", Price = 49.99m, Quantity = 5 });
			foreach (var product in products)
				Console.WriteLine(product);

			Console.WriteLine(Product.Checkout(products));
			Console.ReadLine();
		}
	}

	class Product
	{
		public string Name { get; set; }
		public decimal Price { get; set; }
		public int Quantity { get; set; }
		public decimal Total { get { return Price * Quantity; } }

		// Uh-oh, no constructors defined...
		//public Product(string name, decimal price)
		//{
		//     Console.WriteLine("IN CONSTRUCTOR WITH PARAMETERS");
		//     Name = name;
		//     Price = price;
		//}

		// Removed parameter-less constructor
		//Product()
		//{
		//     Console.WriteLine("IN PARAMETERLESS CONSTRUCTOR");
		//}

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

		public static string Checkout(IEnumerable<Product> products)
		{
			return string.Format("Total cost: {0:C2}", products.Sum(x => x.Total));
		}

		public override string ToString()
		{
			return string.Format("{0} of {1} at {2:C2} = {3:C2}", Quantity, Name, Price, Total);
		}
	}
}

Open in new window

-saige-
it_saigeDeveloperCommented:
And finally, to further illustrate that we are not using a constructor but, rather, initializing properties, let's say we remove the Quantity property initialization on the Product instances that are created by the GetSampleProducts() method [remember we are still using the implied public parameter-less constructor].  What do you think happens then?
using System;
using System.Collections.Generic;
using System.Linq;

namespace EE_Q28705107
{
	class Program
	{
		static void Main(string[] args)
		{
			var products = Product.GetSampleProducts();
			// I'm going to add a new Product to my products list.
			products.Add(new Product { Name = "Mad Max", Price = 49.99m, Quantity = 5 });
			foreach (var product in products)
				Console.WriteLine(product);

			Console.WriteLine(Product.Checkout(products));
			Console.ReadLine();
		}
	}

	class Product
	{
		public string Name { get; set; }
		public decimal Price { get; set; }
		public int Quantity { get; set; }
		public decimal Total { get { return Price * Quantity; } }

		// Uh-oh, no constructors defined...
		//public Product(string name, decimal price)
		//{
		//     Console.WriteLine("IN CONSTRUCTOR WITH PARAMETERS");
		//     Name = name;
		//     Price = price;
		//}

		// Removed parameter-less constructor
		//Product()
		//{
		//     Console.WriteLine("IN PARAMETERLESS CONSTRUCTOR");
		//}

		public static List<Product> GetSampleProducts()
		{
			return new List<Product>
			{
				new Product { Name = "West Side Stroy", 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 }
			};
		}

		public static string Checkout(IEnumerable<Product> products)
		{
			return string.Format("Total cost: {0:C2}", products.Sum(x => x.Total));
		}

		public override string ToString()
		{
			return string.Format("{0} of {1} at {2:C2} = {3:C2}", Quantity, Name, Price, Total);
		}
	}
}

Open in new window

Produces the following output -Capture.JPG-saige-
IzzyTwinklyAuthor Commented:
Wow. Thanks for your time and explanation!!!
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C#

From novice to tech pro — start learning today.