Implement Enum, Struct, and Record in a Banking Application
Enums, structs, and records are fundamental concepts in C# that allow you to define and manage data in a structured and efficient way. In this exercise, you will implement these concepts in a banking application. You will define an enum for account types, a struct for transactions, and a record for customer details. Additionally, you will implement a class to manage bank accounts and demonstrate how these concepts work together in a real-world scenario.
This exercise takes approximately 30 minutes to complete.
Before you start
Before you can start this exercise, you need to:
-
Ensure that you have the latest short term support (STS) version of the .NET SDK installed on your computer. You can download the latest versions of the .NET SDK using the following URL: Download .NET
-
Ensure that you have Visual Studio Code installed on your computer. You can download Visual Studio Code using the following URL: Download Visual Studio Code
-
Ensure that you have the C# Dev Kit configured in Visual Studio Code.
For additional help configuring the Visual Studio Code environment, see Install and configure Visual Studio Code for C# development
Exercise scenario
Suppose you’re a software developer at a tech company working on a new project. Your team needs to implement a banking application that uses enums, structs, and records to manage account types, transactions, and customer details. To ensure consistent behavior, you decide to create and implement these features in a simple console application.
You’ve developed an initial version of the app that includes the following files:
Program.cs
: This file contains the main entry point of the application, demonstrating how to use enums, structs, and records in a banking application.Bank.cs
: This file defines theAccountType
enum,Transaction
struct,Customer
record, andBankAccount
class.
This exercise includes the following tasks:
- Define the
AccountType
enum. - Define the
Transaction
struct. - Define the
Customer
record. - Implement the
BankAccount
class. - Display basic bank account information.
- Perform transactions.
- Display transaction history.
- Demonstrate record comparison.
- Demonstrate immutability of structs.
Review the current version of your project
In this task, you download the existing version of your project and review the code.
Use the following steps to complete this section of the exercise:
-
Download the starter code from the following URL: Implement Collection Types - exercise code projects
-
Extract the contents of the LP4SampleApps.zip file to a folder location on your computer.
-
Expand the LP4SampleApps folder, and then open the
Data_M3
folder.The Data_M3 folder contains the following code project folders:
- Solution
- Starter
The Starter folder contains the starter project files for this exercise.
-
Use Visual Studio Code to open the Starter folder.
-
In the EXPLORER view, collapse the STARTER folder, select SOLUTION EXPLORER, and expand the Data_M3 project.
You should see the following project files:
- Program.cs
- Bank.cs
-
Take a few minutes to open and review the Program.cs and Bank.cs files.
Program.cs
: This file contains the main entry point of the application, demonstrating how to use enums, structs, and records in a banking application.Bank.cs
: This file defines theAccountType
enum,Transaction
struct,Customer
record, andBankAccount
class.
-
Run the app and review the output in the terminal window.
To run your app, right-click the Data_M3 project in the Solution Explorer, select Debug, and then select Start New Instance.
[!TIP] If you encounter any issues while completing this exercise, review the provided code snippets and compare them to your own code. Pay close attention to the syntax and structure of the code. If you’re still having trouble, you can review the solution code in the sample apps that you downloaded at the beginning of this exercise. To view the Data_M3 solution, navigate to the LP4SampleApps/Data_M3/Solution folder and open the Solution project in Visual Studio Code.
Task 1: Define the AccountType
enum
In this task, you’ll define an enum named AccountType
to represent different types of bank accounts. Enums are a great way to define a set of named constants, making your code more readable and maintainable.
Use the following steps to complete this task:
-
Open the
Bank.cs
file in the Starter folder. -
Locate the placeholder comment for Task 1.
- Define an enum named
AccountType
with the following values:Checking
Savings
Business
Your
AccountType
enum should look like this:public enum AccountType { Checking, Savings, Business }
- Save your changes.
What you should see
The AccountType
enum defines a set of named constants (Checking
, Savings
, Business
) that represent different types of bank accounts. This makes the code more readable and ensures consistent account type values throughout the application.
Task 2: Define the Transaction
struct
In this task, you’ll define a struct named Transaction
to represent individual transactions in the banking application. Structs are value types in C# that are ideal for representing small, immutable objects.
Use the following steps to complete this task:
-
Open the
Bank.cs
file in the Starter folder. -
Locate the placeholder comment for Task 2.
- Define a struct named
Transaction
with the following properties:Amount
(type:double
)Date
(type:DateTime
)Description
(type:string
)
-
Add a constructor to initialize the properties of the
Transaction
struct. -
Override the
ToString
method to return a formatted string that includes the date, description, and amount of the transaction.Your
Transaction
struct should look like this:public readonly struct Transaction { public double Amount { get; } public DateTime Date { get; } public string Description { get; } public Transaction(double amount, DateTime date, string description) { Amount = amount; Date = date; Description = description; } public override string ToString() { return $"{Date.ToShortDateString()}: {Description} - {Amount:C}"; } }
- Save your changes.
What you should see
The Transaction
struct represents individual transactions with properties for the amount, date, and description. It uses a constructor for initialization and overrides the ToString
method to format transaction details for display.
Task 3: Define the Customer
record
In this task, you’ll define a record named Customer
to represent customer details in the banking application. Records are immutable reference types in C# that are ideal for representing data with value-based equality.
Use the following steps to complete this task:
-
Open the
Bank.cs
file in the Starter folder. -
Locate the placeholder comment for Task 3.
- Define a record named
Customer
with the following properties:Name
(type:string
)CustomerId
(type:string
)Address
(type:string
)
Your
Customer
record should look like this:public record Customer(string Name, string CustomerId, string Address);
- Save your changes.
What you should see
The Customer
record is an immutable data type that represents customer details, such as name, ID, and address. Records in C# provide value-based equality, making them ideal for representing data objects.
Task 4: Implement the BankAccount
class
In this task, you’ll implement the BankAccount
class to manage bank accounts in the application. This class will include properties, a constructor, and methods to handle account operations such as deposits, withdrawals, and displaying account information.
Use the following steps to complete this task:
-
Open the
Bank.cs
file in the Starter folder. -
Locate the placeholder comment for Task 4.
- Add the following properties to the
BankAccount
class:AccountNumber
(type:int
, read-only)Type
(type:AccountType
, read-only)AccountHolder
(type:Customer
, read-only)Balance
(type:double
, private set)
- Add a constructor to initialize the properties of the
BankAccount
class. The constructor should accept the following parameters:accountNumber
(type:int
)type
(type:AccountType
)accountHolder
(type:Customer
)initialBalance
(type:double
, optional, default value:0
)
Your constructor should look like this:
public BankAccount(int accountNumber, AccountType type, Customer accountHolder, double initialBalance = 0) { AccountNumber = accountNumber; Type = type; AccountHolder = accountHolder; Balance = initialBalance; }
- Add a method named
AddTransaction
to deposit money into the account. This method should:- Accept two parameters:
amount
(type:double
) anddescription
(type:string
). - Update the
Balance
property by adding theamount
. - Add a new
Transaction
to a private list of transactions.
- Accept two parameters:
-
Add a method named
DisplayAccountInfo
to return a formatted string with the account holder’s name, account number, account type, and balance.Your
DisplayAccountInfo
method should look like this:public string DisplayAccountInfo() { return $"Account Holder: {AccountHolder.Name}, Account Number: {AccountNumber}, Type: {Type}, Balance: {Balance:C}"; }
- Add a private list of transactions to the class:
private List<Transaction> Transactions { get; } = new();
-
Add a method named
DisplayTransactions
to iterate through the list of transactions and print each transaction to the console.Your
DisplayTransactions
method should look like this:public void DisplayTransactions() { Console.WriteLine("Transactions:"); foreach (var transaction in Transactions) { Console.WriteLine(transaction); } }
- Save your changes.
What you should see
The BankAccount
class ties together the AccountType
enum, Transaction
struct, and Customer
record to manage bank accounts. It includes properties, a constructor, and methods for handling deposits, withdrawals, and displaying account information.
Task 5: Display Basic Bank Account Information
In this task, you’ll use the BankAccount
class to display basic account information, including the account holder’s name, account number, account type, and balance.
Use the following steps to complete this task:
-
Open the
Program.cs
file in the Starter folder. -
Locate the placeholder comment for Task 5.
- Create a
Customer
object to represent the account holder. Use the following values:Name
:"Tim Shao"
CustomerId
:"C123456789"
Address
:"123 Elm Street"
Your
Customer
object should look like this:Customer customer1 = new("Tim Shao", "C123456789", "123 Elm Street");
- Create a
BankAccount
object to represent the account. Use the following values:AccountNumber
:12345678
Type
:AccountType.Checking
AccountHolder
:customer1
InitialBalance
:500
Your
BankAccount
object should look like this:BankAccount account = new(12345678, AccountType.Checking, customer1, 500);
-
Call the
DisplayAccountInfo
method on theBankAccount
object and print the result to the console.Your code should look like this:
Console.WriteLine(account.DisplayAccountInfo());
- Save your changes.
What you should see
The DisplayAccountInfo
method outputs the account holder’s name, account number, account type, and balance. This demonstrates how the BankAccount
class integrates with the Customer
record and AccountType
enum.
Run the project
Save your changes and run the project to verify the output. You should see the following in the terminal:
Account Holder: Tim Shao, Account Number: 12345678, Type: Checking, Balance: $500.00
Task 6: Perform Transactions
In this task, you’ll use the BankAccount
class to perform transactions, including deposits and withdrawals. You’ll also display the updated account information after each transaction.
Use the following steps to complete this task:
-
Open the
Program.cs
file in the Starter folder. -
Locate the placeholder comment for Task 6.
- Call the
AddTransaction
method on theBankAccount
object to perform a deposit. Use the following values:Amount
:200
Description
:"Deposit"
Your code should look like this:
account.AddTransaction(200, "Deposit");
-
Print the updated account information to the console by calling the
DisplayAccountInfo
method.Your code should look like this:
Console.WriteLine("After deposit:"); Console.WriteLine(account.DisplayAccountInfo());
- Call the
AddTransaction
method on theBankAccount
object to perform a withdrawal. Use the following values:Amount
:-50
Description
:"ATM Withdrawal"
Your code should look like this:
account.AddTransaction(-50, "ATM Withdrawal");
-
Print the updated account information to the console by calling the
DisplayAccountInfo
method.Your code should look like this:
Console.WriteLine("After withdrawal:"); Console.WriteLine(account.DisplayAccountInfo());
- Save your changes.
What you should see
The AddTransaction
method updates the account balance and records each transaction in a list. This demonstrates how the Transaction
struct is used to track deposits and withdrawals.
Run the project
Save your changes and run the project to verify the output. You should see the following in the terminal:
After deposit: Account Holder: Tim Shao, Account Number: 12345678, Type: Checking, Balance: $700.00
After withdrawal: Account Holder: Tim Shao, Account Number: 12345678, Type: Checking, Balance: $650.00
Task 7: Display Transaction History
In this task, you’ll use the BankAccount
class to display the transaction history for an account. This will include all deposits and withdrawals made on the account.
Use the following steps to complete this task:
-
Open the
Program.cs
file in the Starter folder. -
Locate the placeholder comment for Task 7.
-
Call the
DisplayTransactions
method on theBankAccount
object to print the transaction history to the console.Your code should look like this:
account.DisplayTransactions();
-
Save your changes.
What you should see
The DisplayTransactions
method iterates through the list of transactions and prints each one to the console. This demonstrates how the Transaction
struct and collections work together to manage and display transaction history.
Run the project
Save your changes and run the project to verify the output. You should see the following in the terminal:
Transactions: 4/1/2025: Deposit - $200.00 4/1/2025: ATM Withdrawal - ($50.00)
Task 8: Demonstrate Record Comparison
In this task, you’ll demonstrate how C# records support value-based equality by creating and comparing two Customer
objects with identical properties.
Use the following steps to complete this task:
-
Open the
Program.cs
file in the Starter folder. -
Locate the placeholder comment for Task 8.
- Create two
Customer
objects with identical properties. Use the following values for both objects:Name
:"Tim Shao"
CustomerId
:"C123456789"
Address
:"123 Elm Street"
Your code should look like this:
Customer customer1 = new("Tim Shao", "C123456789", "123 Elm Street"); Customer customer2 = new("Tim Shao", "C123456789", "123 Elm Street");
-
Compare the two
Customer
objects using the==
operator and print the result to the console.Your code should look like this:
Console.WriteLine($"Are customers equal? {customer1 == customer2}");
- Save your changes.
What you should see
The comparison of two Customer
objects demonstrates value-based equality in C# records. Even though the objects are separate instances, they are considered equal because their property values are identical.
Run the project
Save your changes and run the project to verify the output. You should see the following in the terminal:
Are customers equal? True
Task 9: Demonstrate Immutability of Structs
In this task, you’ll demonstrate the immutability of structs by creating a Transaction
object and displaying its details. Structs in C# are value types and are immutable when their properties are read-only.
Use the following steps to complete this task:
-
Open the
Program.cs
file in the Starter folder. -
Locate the placeholder comment for Task 9.
- Create a
Transaction
object to represent a transaction. Use the following values:Amount
:100
Date
:DateTime.Now
Description
:"Test Transaction"
Your code should look like this:
Transaction transaction = new(100, DateTime.Now, "Test Transaction");
-
Print the details of the
Transaction
object to the console by calling itsToString
method.Your code should look like this:
Console.WriteLine($"Immutable Transaction: {transaction}");
- Save your changes.
What you should see
The Transaction
struct is immutable because its properties are read-only. Once a Transaction
object is created, its values cannot be changed, ensuring data integrity.
Run the project
Save your changes and run the project to verify the output. You should see the following in the terminal:
Immutable Transaction: 4/1/2025: Test Transaction - $100.00
Check your work
After completing all tasks, save your work and run the application to verify that all functionality is implemented correctly. Ensure that the application builds successfully and produces the expected output for each task.
Run the project
-
Open the
Program.cs
file in the Starter folder. -
Run the application by selecting Debug > Start Without Debugging in Visual Studio Code or by using the terminal command:
dotnet run
-
Verify that the application produces the following output in the terminal:
Account Holder: Tim Shao, Account Number: 12345678, Type: Checking, Balance: $500.00
After deposit:
Account Holder: Tim Shao, Account Number: 12345678, Type: Checking, Balance: $700.00
After withdrawal:
Account Holder: Tim Shao, Account Number: 12345678, Type: Checking, Balance: $650.00
Transactions:
4/1/2025: Deposit - $200.00
4/1/2025: ATM Withdrawal - ($50.00)
Are customers equal? True
Immutable Transaction: 4/1/2025: Test Transaction - $100.00
Clean up
Now that you’ve finished the exercise, consider archiving your project files for review at a later time. Having your own projects available for review can be a valuable resource when you’re learning to code. Additionally, building a portfolio of projects can be a great way to demonstrate your skills to potential employers.
If you no longer need the project files, you can delete the folder to free up space on your computer. However, it’s recommended to keep a copy of the completed project for future reference or as part of your coding portfolio.