×

c# · level 3 · unit 1 · lesson 4

  1. meet it
  2. guess first
  3. your turn
  4. fix it
  5. nailed it

Tap a green word if you get lost.

meet it

A constraint can name your own interface, or demand new().

Constraints can name your own interfaces. where T : IHasId lets a generic class read item.Id from any type that promises one. That is enough for a : one class that stores and finds products, customers or orders by id, written once.

When nothing matches, return default: the empty value of whatever T is. That is null for classes and records, 0 for int and false for bool. You cannot write null there, because T might be a number.

Stack constraints with commas. Adding the , as in where T : IHasId, new(), allows new T() inside.

using System;
using System.Collections.Generic;

var shelf = new Repository<Product>();
shelf.Add(new Product(7, "kettle"));
shelf.Add(new Product(9, "toaster"));
Console.WriteLine(shelf.Find(9).Name);
Console.WriteLine(shelf.Find(3) == null);

interface IHasId { int Id { get; } }

record Product(int Id, string Name) : IHasId;

class Repository<T> where T : IHasId
{
    private Dictionary<int, T> items = new Dictionary<int, T>();
    public void Add(T item) => items[item.Id] = item;
    public T Find(int id)
    {
        if (items.ContainsKey(id)) return items[id];
        return default;
    }
}

The record's Id already has a get, so Product keeps the promise IHasId makes.