C# Programming Foundation
Before you start
You need: stage 1, and a working Visual Studio installation.
Time: 36–44 classes. This is the longest stage and everything after it depends on it.
Learning objective
Build the C# competence every later stage assumes — types, control flow, classes, collections, LINQ, exceptions and async.
Topics
- C# and .NET fundamentals
- Types, and why money is
decimal - Control flow, and why condition order decides correctness
- Classes, encapsulation and interfaces
- Collections and LINQ
- Exceptions, files and JSON
async/await- Debugging with breakpoints
What this stage covers
This is the longest stage of the path — 36 to 44 classes — and everything after it depends on it. An API is C#. A repository is C#. A service is C#. Weakness here surfaces as confusion in stage 5, not stage 2.
| Concept | Used later in |
|---|---|
| Classes and properties | Entities and DTOs, stages 4 and 5 |
| Interfaces | The repository pattern, stage 4 |
| Collections and LINQ | Every service method, stage 5 |
decimal | Every fee amount, stages 3 to 10 |
| Nullable types | Absent exam results, throughout |
| Exceptions | API error handling, stage 5 |
async/await | Every database and HTTP call |
| Breakpoints | Stage 8, and every day after |
Three rules established here recur in every remaining stage:
- Money is
decimal, neverdouble. Floating-point arithmetic does not sum exactly, and a fee report off by paise is always this. - An absent exam result is
null, never0, and the absent check comes first in any grading chain. Stored as0, the class average is silently wrong. - Look-ups can return nothing.
FirstOrDefaultplus a null check, notFirst.
Worked flow: the fee receipt
At this stage the receipt exists as C# classes and one calculation — no database, no API, no screen.
public class FeeReceipt
{
public string ReceiptNumber { get; set; }
public string StudentName { get; set; }
public string RollNumber { get; set; }
public string ClassName { get; set; }
public decimal AmountPaid { get; set; }
public DateTime PaidOn { get; set; }
public PaymentMode PaymentMode { get; set; }
public decimal BalanceAfterPayment { get; set; }
}
public class ReceiptService
{
public FeeReceipt Build(Student student, FeeAccount account, FeePayment payment)
{
if (student == null)
{
throw new ArgumentNullException(nameof(student));
}
if (account == null)
{
throw new ArgumentNullException(nameof(account));
}
decimal balanceAfter = account.TotalFees - account.DiscountAmount - account.PaidAmount;
FeeReceipt receipt = new FeeReceipt();
receipt.ReceiptNumber = payment.ReceiptNumber;
receipt.StudentName = student.Name;
receipt.RollNumber = student.RollNumber;
receipt.ClassName = $"{student.ClassName}-{student.Section}";
receipt.AmountPaid = payment.Amount;
receipt.PaidOn = payment.PaidOn;
receipt.PaymentMode = payment.PaymentMode;
receipt.BalanceAfterPayment = balanceAfter;
return receipt;
}
}
Every value here is decimal. Every guard clause comes first. The class does one thing, and it can be unit tested with no database, no API and no browser — which is exactly why the calculation lives in a service and not in a screen.
Where to learn it
| Topic | Read |
|---|---|
| .NET, the SDK, the first project | Track 03 — .NET and setup |
Types, decimal, nullable, parsing | Track 03 — Types and operators |
| Conditions, loops, methods | Track 03 — Control flow and methods |
| Classes, encapsulation, interfaces | Track 03 — Classes and OOP |
| Collections and generics | Track 03 — Collections and generics |
| LINQ | Track 03 — LINQ |
| Exceptions, files, JSON | Track 03 — Errors, files and JSON |
async/await | Track 03 — Async and await |
| Debugging and unit tests | Track 03 — Debugging and quality |
| The console capstone | Track 03 — Student Marks Application |
Do the whole of Track 03, including the capstone. The Student Marks Application is where absent handling, decimal arithmetic and unit testing become habits rather than facts.
Stage exercises
From the guided path syllabus:
Build and test one CRUD feature. In a console application, implement add, list, update and deactivate for Student, held in a List<Student> behind an IStudentRepository. Later stages replace the list with SQL Server without changing the interface — which is the point.
Model the receipt. Write FeeReceipt, FeeAccount and FeePayment as classes, and ReceiptService.Build as above. Unit test it for a full payment, a partial payment, and a payment on an account with a discount.
Debugging drills
Fix a mapping error. Deliberately assign PaidOn where DueDate belongs and watch the receipt show a wrong date with no exception. Find it with a breakpoint on Build and the Locals window.
Trace a loop and a method call. Loop over 40 exam results with a conditional breakpoint on result.StudentId == 12, and read the Call Stack to see which method supplied the argument.
Fix null, index and parsing errors. Trigger each deliberately — a repository returning null, a CSV row with a missing field, int.Parse on a roll number — and fix each with the two-line guard rather than a try/catch.
Practice
- Work through Track 03's ten articles and their practice lists.
- Build the Student Marks Application capstone.
- Model
FeeReceipt,FeeAccountandFeePayment, and writeReceiptService.Build. - Unit test the receipt for full payment, partial payment and a discounted account.
- Compute a fee total as
doubleand asdecimalover a thousand payments, and compare. - Write the grading chain with the absent check last, run it for an absent student, then fix the order.
- Implement
IStudentRepositoryover an in-memory list, with add, list, update and deactivate. - Write a
FirstOrDefaultlookup with a null check, then replace it withFirstand see what a missing student does. - Debug a wrong receipt date using a breakpoint and Locals rather than print statements.
- Convert a synchronous repository method to
async Task<T>and await it fromMain.
You can now
- Write, debug and explain structured C#
- Model School entities as classes with encapsulation
- Use collections, generics, delegates and LINQ
- Handle exceptions without hiding them
- Write async methods correctly
- Debug in Visual Studio and write a unit test
Review questions
- Why is every money value in this stage
decimal? - Why does
ReceiptService.Buildlive in a service rather than in a screen? - What does
IStudentRepositorylet you change later without touching the service? - Why must the absent check come first?
Next: SQL Server foundation