Chapter 10: Mini Project – Console-based Expense Tracker
In this chapter, we build a Console-based Expense Tracker application in C#.
This project integrates concepts from previous chapters: variables, data types, control flow, methods, OOP, data structures, LINQ, and async programming.
🎯 What You Will Learn
By the end of this chapter, you will:
- Apply programming fundamentals in a real-world project
- Design classes and objects for expense management
- Use collections (Lists, Dictionaries) to store data
- Implement CRUD operations (Add, View, Update, Delete)
- Use LINQ for querying and reporting expenses
- Apply async methods for saving/loading data
- Practice modular design and encapsulation
🔹 Project Overview
The Expense Tracker will allow users to:
- Add new expenses (amount, category, description, date)
- View all expenses
- Search/filter expenses by category or date
- Calculate totals and summaries
- Save and load expenses asynchronously (simulated with files)
🔹 Step 1: Define the Expense Class
using System;
class Expense
{
public int Id { get; set; }
public double Amount { get; set; }
public string Category { get; set; }
public string Description { get; set; }
public DateTime Date { get; set; }
public override string ToString()
{
return $"[{Id}] {Date.ToShortDateString()} - {Category} - {Description} - ${Amount}";
}
}
👉 Exercise:
- Add a property
PaymentMode(Cash/Card/UPI). - Update
ToString()to include it.
🔹 Step 2: Expense Manager Class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
class ExpenseManager
{
private List<Expense> expenses = new List<Expense>();
private int nextId = 1;
public void AddExpense(double amount, string category, string description, DateTime date)
{
Expense e = new Expense
{
Id = nextId++,
Amount = amount,
Category = category,
Description = description,
Date = date
};
expenses.Add(e);
Console.WriteLine("Expense added successfully!");
}
public void ViewExpenses()
{
foreach (var e in expenses)
{
Console.WriteLine(e);
}
}
public void DeleteExpense(int id)
{
var expense = expenses.FirstOrDefault(e => e.Id == id);
if (expense != null)
{
expenses.Remove(expense);
Console.WriteLine("Expense deleted.");
}
else
{
Console.WriteLine("Expense not found.");
}
}
public void SummaryByCategory()
{
var summary = expenses.GroupBy(e => e.Category)
.Select(g => new { Category = g.Key, Total = g.Sum(e => e.Amount) });
foreach (var s in summary)
{
Console.WriteLine($"{s.Category}: ${s.Total}");
}
}
public async Task SaveToFileAsync(string filePath)
{
var lines = expenses.Select(e => $"{e.Id},{e.Amount},{e.Category},{e.Description},{e.Date}");
await System.IO.File.WriteAllLinesAsync(filePath, lines);
Console.WriteLine("Expenses saved to file.");
}
public async Task LoadFromFileAsync(string filePath)
{
if (System.IO.File.Exists(filePath))
{
var lines = await System.IO.File.ReadAllLinesAsync(filePath);
foreach (var line in lines)
{
var parts = line.Split(',');
expenses.Add(new Expense
{
Id = int.Parse(parts[0]),
Amount = double.Parse(parts[1]),
Category = parts[2],
Description = parts[3],
Date = DateTime.Parse(parts[4])
});
}
Console.WriteLine("Expenses loaded from file.");
}
}
}
👉 Exercise:
- Add a method
SearchByDate(DateTime date)to filter expenses by date.
🔹 Step 3: Program Entry Point
using System;
class Program
{
static async System.Threading.Tasks.Task Main()
{
ExpenseManager manager = new ExpenseManager();
bool exit = false;
while (!exit)
{
Console.WriteLine("\n--- Expense Tracker ---");
Console.WriteLine("1. Add Expense");
Console.WriteLine("2. View Expenses");
Console.WriteLine("3. Delete Expense");
Console.WriteLine("4. Summary by Category");
Console.WriteLine("5. Save to File");
Console.WriteLine("6. Load from File");
Console.WriteLine("7. Exit");
Console.Write("Choose an option: ");
int choice = int.Parse(Console.ReadLine());
switch (choice)
{
case 1:
Console.Write("Amount: ");
double amount = double.Parse(Console.ReadLine());
Console.Write("Category: ");
string category = Console.ReadLine();
Console.Write("Description: ");
string description = Console.ReadLine();
Console.Write("Date (yyyy-mm-dd): ");
DateTime date = DateTime.Parse(Console.ReadLine());
manager.AddExpense(amount, category, description, date);
break;
case 2:
manager.ViewExpenses();
break;
case 3:
Console.Write("Enter Expense ID to delete: ");
int id = int.Parse(Console.ReadLine());
manager.DeleteExpense(id);
break;
case 4:
manager.SummaryByCategory();
break;
case 5:
await manager.SaveToFileAsync("expenses.txt");
break;
case 6:
await manager.LoadFromFileAsync("expenses.txt");
break;
case 7:
exit = true;
break;
default:
Console.WriteLine("Invalid choice.");
break;
}
}
}
}
🔹 Sample Run
--- Expense Tracker ---
1. Add Expense
2. View Expenses
3. Delete Expense
4. Summary by Category
5. Save to File
6. Load from File
7. Exit
Choose an option: 1
Amount: 100
Category: Food
Description: Lunch
Date (yyyy-mm-dd): 2026-04-28
Expense added successfully!
📘 Chapter Summary
In this chapter, you built a Console-based Expense Tracker that demonstrated:
- Classes and Objects for modeling expenses
- Lists and LINQ for storing and querying data
- CRUD operations for managing expenses
- Async methods for saving and loading data
- Encapsulation and modular design
👉 This project consolidates all fundamentals into a practical application.