WeCodeAcademy

Step 6: Port the core to C#

The same design works in C#: the languages are close cousins. Here the borrowing rules are ported: Book uses auto-properties ({ get; set; }), the service keeps a Dictionary<string, List<Book>> of loans, and rule violations throw InvalidOperationException. Compare it with step 4 and notice how little changes: that is the point of designing with classes and responsibilities rather than language tricks.

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

class Book
{
    public string Isbn { get; }
    public string Title { get; }
    public bool Available { get; set; } = true;

    public Book(string isbn, string title)
    {
        Isbn = isbn;
        Title = title;
    }
}

class LibraryService
{
    private const int MaxLoans = 2;
    private readonly Dictionary<string, List<Book>> loans = new Dictionary<string, List<Book>>();

    public void Borrow(string member, Book book)
    {
        if (!book.Available)
            throw new InvalidOperationException(book.Title + " is already on loan");
        if (!loans.ContainsKey(member))
            loans[member] = new List<Book>();
        if (loans[member].Count >= MaxLoans)
            throw new InvalidOperationException(member + " has reached the limit of " + MaxLoans + " loans");
        book.Available = false;
        loans[member].Add(book);
    }

    public int Count(string member)
    {
        return loans.ContainsKey(member) ? loans[member].Count : 0;
    }
}

class Program
{
    static void Main()
    {
        var library = new LibraryService();
        var a = new Book("1", "Clean Code");
        var b = new Book("2", "Refactoring");
        var c = new Book("3", "Design Patterns");

        foreach (var book in new[] { a, b, c, a })
        {
            try
            {
                library.Borrow("Ada", book);
                Console.WriteLine("OK    " + book.Title);
            }
            catch (InvalidOperationException e)
            {
                Console.WriteLine("ERROR " + e.Message);
            }
        }
        Console.WriteLine("Ada has " + library.Count("Ada") + " loans");
    }
}
Output
OK    Clean Code
OK    Refactoring
ERROR Ada has reached the limit of 2 loans
ERROR Clean Code is already on loan
Ada has 2 loans

(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.)

Quick check

Which C# feature replaces Java getter and setter methods?

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.