Properties Syntax refactoring some code - Lab

by Carla Goncalves
on April 13, 2018
C# Properties, Expression Bodied Elements, Auto-Implemented Properties, Fields, Encapsulation

Goal:
The objective of this lab is to use the full variety of property syntax to encapsulate data. Also to be able to distinguish which property type is appropriate in each circumstance.

What are properties for ?
First let state that fields are data members capable of storing data.

		// private field
		private string accountHolder;

		// public field (Generally not recommended.)
		public string name;

Property procedures encapsulate fields (which means when you create a property the field is STILL there but the compiler cleverly hides it from you ). With properties you can use logic and perform other functions such as validation which is a very powerful feature. Properties are used as they are public data members but they are special methods called accessors i.e get and set methods.

		// propg tab example of a auto-implemented property
		public  string  holder   	{ get; private set; }
		public  decimal balance	    { get; private set; }
	  
		
		

It’s a way to access private fields (read, write, compute) and set their values. There is 3 types of properties : read/write readOnly and writeOnly;

Overview
This practical will build on the solution of the previous practical where class Account was authored with several ‘get’ methods and private fields but no encapsulation via property procedures.

Project output

console output

Code to be refractored:

using System;

namespace Finance
{
	public class Account
	{
		// private instance fields
		public  string  holder   { get; private set; }
		public  decimal balance  { get; private set; }
		public  string  accNo    { get; private set; }
		
		// private static fields
		private static int nxtAccNo;
		private static decimal overdraftLimit = 500;

		//ctors
		public Account(string name, decimal balance)
		{
			holder = name;
			this.balance = balance;
			accNo = "SA-" + (++nxtAccNo).ToString().PadLeft(4, '0');
		}
		
		public Account(string name) : this(name, 0) { }

		public string GetDetails()
		{
			return string.Format("{0}\t{1}\t{2:C}", accNo, holder, balance);
		}

		public decimal GetBalance()
		{
			return balance;
		}
		
		public string GetHolder()
		{
			return holder;
		}

		public void Deposit(decimal amt)
		{
			balance += amt;
		}
		
		public bool Withdraw(decimal amt)
		{
			bool result = false;
			if (amt <= this.balance + Account.overdraftLimit)
			{
				balance -= amt;
				result = true;
			}

			return result;
		}

		public static bool Transfer(Account from, Account to, decimal amt)
		{
			bool result = false;

			if (from.Withdraw(amt))
			{
				to.Deposit(amt);
				result = true;
			}
			Console.WriteLine("Transfer of {0:C} Successful: {1}", amt, result ? "YES" : "NO");
			return result;
		}

	}
}

Replace the instance variables for auto implemented properties and static field

Auto implemented properties is the compiler creates a private, anonymous backing field that can only be accessed through the property's get and set accessors (propg). You use auto implemented properties when you don't need to use any logic over data


"In class Account remove the 3 instance variables ‘holder’, ‘balance’ and ‘accNo’. Replace them (use ‘propg’ code snippet) with 3 auto-implemented properties called Holder, Balance, and AccNo. Remove static field ‘nxtAccno’ and replace it (use ‘propg’ again) with a static property called NxtAccNo.

Update the class constructor, and methods GetDetails(), Deposit() and WithDraw() to use these new properties (Ctrl-Space will help!)."

		public  string  holder   	 { get; private set; }
		public  decimal balance	       { get; private set; }
		public  string  accNo   	 { get; private set; }

Go to class Program, Main method where several changes are needed to use the new properties instead of the deleted GetXXX methods. Build the project.

Author a new property in class Account called TotalFundsAvailable. This is a totally calculated value so it has no backing field and will consist of just a ‘get’ block.
I will use an EXPRESSION-BODIED MEMBERS which is just a single expression that returns a value that matches with the method return type. Basically replaces the return keyword with =>

	public decimal TotalFundsAvailable => balance + Account.OverdraftLimit;

"Amend the foreach loop in method Print so that as well as displaying the details of the Account you also display the TotalFundsAvailable.""

private static void Print(Account[] studentAccs)
{
	foreach (Account a in studentAccs)
	{

		Console.WriteLine("{0}\tAvailableFunds={1}", a.GetDetails, a.TotalFundsAvailable);
	}

}

Once this loop change is completed, re-run your code. Check that for the 5 girls accounts that it displays TotalFundsAvailable correctly.

Currently the static field overdraftLimit which is initialised to the value 500 is not encapsulated behind a property.

For that i need to write a public decimal overdraftLimit. However if I wrote it as as auto-implemented I wouldn't have no backing field to easily initialize to a default value of 500. Therefore it will be encapsulated behind a property with a fully get and set block and take the oportunity to validate and value passed to its setter as ovedraft limit and never let it be a negative value.

	public static decimal OverdraftLimit
	{
		get => overdraftLimit; 
		private set
		{
			if (value >= 0)             // validate incoming value
			{
				overdraftLimit = value;
			}
		}
	};

GetDetails() can also be rewritten

public string GetDetails => string.Format("{0}\t{1}\t{2:C}", accNo, holder, balance);

Write the following line of code as the 1st statement of your Main method Account.OverdraftLimit = 700;
Rerun your code to see the difference.


You might want to read...
DailyUI,Css Daily UI #2- Image scrolling on hover

Scrolling hover effect Images - Css only...

DailyUI Daily UI - Rethinking the user experience #1

Transitions, delays, gradients, Jquery and et al....

WordPress/Bootstrap How to use Bootstrap Carousel with WordPress posts Loop

Bootstrap can be a bit tricky to make it work dynamically with your WP data...