WeCodeAcademy

Step 8: A C# port, and what you built

Finally, the same account in C#. The shape is nearly identical: a private field, a read-only property (public long Balance => cents;), validation, a custom exception, and a read-only view of the history (IReadOnlyList). This is the point of learning design: the ideas (invariants, encapsulation, all-or-nothing, immutability) carry across languages.

ExampleC#
using System;
using System.Collections.Generic;

class InsufficientFundsException : Exception
{
    public InsufficientFundsException(string message) : base(message) { }
}

class Account
{
    private long cents;
    private readonly List<string> history = new List<string>();

    public long Balance => cents;

    public void Deposit(long amount)
    {
        if (amount <= 0) throw new ArgumentException("deposit must be positive");
        cents += amount;
        history.Add("deposit " + amount);
    }

    public void Withdraw(long amount)
    {
        if (amount > cents) throw new InsufficientFundsException("needs " + amount + " but has " + cents);
        cents -= amount;
        history.Add("withdraw " + amount);
    }

    public IReadOnlyList<string> History => history;
}

class Program
{
    static void Main()
    {
        var account = new Account();
        account.Deposit(10000);
        account.Withdraw(2550);
        try
        {
            account.Withdraw(90000);
        }
        catch (InsufficientFundsException e)
        {
            Console.WriteLine("refused: " + e.Message);
        }
        foreach (var line in account.History) Console.WriteLine(line);
        Console.WriteLine("balance " + account.Balance);
    }
}
Output
refused: needs 90000 but has 7450
deposit 10000
withdraw 2550
balance 7450

(The C# output was worked out by hand: no .NET compiler was available when this lesson was written, so run it with dotnet run to confirm.)

You have built the core of a bank: exact money, rule-protecting accounts, all-or-nothing transfers, thread safety, a transactional database design and tests. Where next: add interest, a bank-owned fee account so the books always balance, an overdraft limit per customer, a REST API on top (the Node project shows how), and idempotency keys so a retried transfer request is never applied twice.

Quick check

Which ideas carried over unchanged from Java to C#?

Finish the quick check (and any code exercise) to complete this lesson, or mark it done yourself.

Tip: use the left and right arrow keys to move between lessons.