I am going through the Head First C# book and I can't figure out why they used the following way to create a property. It just seems inconsistent with the convention I'm seeing everywhere else and in the book itself too.
I understand that the pattern for creating properties is:
private int myVar;
public int MyProperty
{
get { return myVar; }
set { myVar = value; }
}
Based on the above pattern I would have written my code like this:
private decimal cost;
public decimal Cost
{
get
{
cost = CalculateCostOfDecorations() + (CalculateCostOfBeveragesPerPerson() + CostOfFoodPerPerson) * NumberOfPeople;
if (HealthyOption)
{
cost *= .95M;
}
return cost;
}
}
In the book it is presented like the following:
public decimal Cost
{
get
{
decimal totalCost = CalculateCostOfDecorations();
totalCost += (CalculateCostOfBeveragesPerPerson() + CostOfFoodPerPerson)*NumberOfPeople;
if (HealthyOption)
{
totalCost *= .95M;
}
return totalCost;
}
}
Both codes work just fine in the program. What is the best practice to create such properties? Is the decimal totalCost inside the property private? If so, why is it not declared before creating the property instead?
Also, what is the point of creating two lines of code:
decimal totalCost = CalculateCostOfDecorations();
totalCost += (CalculateCostOfBeveragesPerPerson() + CostOfFoodPerPerson)*NumberOfPeople;
when you can accomplish the exact same thing by writing:
cost = CalculateCostOfDecorations() + (CalculateCostOfBeveragesPerPerson() + CostOfFoodPerPerson) * NumberOfPeople;
Good book for beginners. I have enjoyed reading through this and have learnt a lot.
It is the best Go book for beginners, period. The Head First C book is said to be equally excellent. So these books are not only “effective”, but usually the #1 educational books for beginners.
There is no doubt that Head First Java 3rd edition is now the best book to learn Java Programming in 2022. It's latest edition covers Java 17 and the latest features from recent Java releases, particularly Java 8 features, but it's still a great book to learn Java for complete beginners.
Amazon.com: Head First Series: Books.
The primary difference between the two samples is, as you have noticed, that one has a backing field (which is what putting decimal cost
outside the property definition does) and the other doesn't.
The totalCost
variable in the second sample isn't a field at all (private
or otherwise), it is simply a variable local to the get
method.
Both are fine, though if you aren't using the backing field for anything, its not really necessary to have. As to your second question, I have no idea why they specifically did it that way, other than to make the variable declaration simpler.
As an aside, both samples are a bit off from standard C# practice, as thats an awful lot of logic for a property getter.
Both ways "work." If you're asking which way is best, I'd say neither.
Since Cost
isn't really a field or property (it is something that is computed, and cannot be set by the caller), it would be more idiomatic to implement as a method which returns a value. No member variable should be needed.
public decimal GetCost()
{
var cost = CalculateCostOfDecorations() + (CalculateCostOfBeveragesPerPerson() + CostOfFoodPerPerson) * NumberOfPeople;
if (HealthyOption)
{
cost *= .95M;
}
return cost;
}
Is the decimal
totalCost
inside the property private? If so, why is it not declared before creating the property instead?
It is created inside the property
to limit its scope. If you declared totalCost
above the property
, it would be accessible throughout the class
itself.
Also, what is the point of creating two lines of code:
Usually, just for readability. One liners are great until you have to keep scrolling to see it in its entirety.
As mentioned by others, neither of these is really idiomatic C#, however having the backing field for this could lead to errors later on in the code, e.g.:
private decimal cost;
public decimal Cost
{
get
{
cost = CalculateCostOfDecorations() + (CalculateCostOfBeveragesPerPerson() + CostOfFoodPerPerson) * NumberOfPeople;
if (HealthyOption)
{
cost *= .95M;
}
return cost;
}
}
public decimal CalculateDiscountedCost() {
return cost * 0.75m; //Note the deliberate mistake?
}
By (possibly accidentally) accessing the backing variable in the subsequent method, rather than the property you could easily develop some hard to maintain code. In this case, the discounted cost may be right when called, but would depend on the public propery Cost
being accessed prior to calling the CalculateDiscountedCost
method in order to set the backing variable.
As the backing variable is essentially unnecessary, it would be be better to do without it.
The totalCost
variable is not private
, it's local variable inside of the getter. The variable does not exist outside of that method so it only takes up memory while the getting is running. Your private cost
field will stay in memory as long as the class instance does. The variable is only ever used inside of the getter so it should be a local in the getter as the book shows. There is no reason for it to be a class field.
The point of creating two lines is so that it can fit a single line on the page. The code is exactly the same; it is just formatted differently.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With