If you ever find yourself wanting to duplicate code with just slight changes to adapt it to use a different type, then you’ll appreciate C# generics. Generic programming is sometimes called template programming because it allows you to write code that will be used later to generate the actual specific code.

Lets say you have a class called Shop and another class called InventoryItem like this:

using System;

public class InventoryItem
{
    public int OriginalValue
    {
        get
        {
            return 5;
        }
    }
}

public class Shop
{
    public int Trade (InventoryItem item)
    {
        return item.OriginalValue;
    }
}

class Program
{
    static void Main(string[] args)
    {
        InventoryItem myItem = new InventoryItem();
        Shop theShop = new Shop();

        Console.WriteLine("The shop will pay {0} silver coins for your item.", theShop.Trade(myItem));
    }
}

You can trade your inventory at the shop and this works well until you need to trade things that may not actually be inventory. So you create an interface called ITradable that any class can implement if it wants to be traded.

using System;

public interface ITradable
{
    int OriginalValue { get; }
}

public class InventoryItem : ITradable
{
    public int OriginalValue
    {
        get
        {
            return 5;
        }
    }
}

public class Service : ITradable
{
    public int OriginalValue
    {
        get
        {
            return 10;
        }
    }
}

public class Shop
{
    public int Trade (ITradable trade)
    {
        return trade.OriginalValue;
    }
}

class Program
{
    static void Main(string[] args)
    {
        InventoryItem myItem = new InventoryItem();
        Service myService = new Service();
        Shop theShop = new Shop();

        Console.WriteLine("The shop will pay {0} silver coins for your item.", theShop.Trade(myItem));
        Console.WriteLine("The shop will pay {0} silver coins for your service.", theShop.Trade(myService));
    }
}

Now you can trade items as well as service. And then you need to make sure that only some items can be traded at certain stores. You could add a new property to the interface to get a category either as a string or some number representation but this approach still has problems as the podcast episode describes. Instead, you make the shop a generic class like this:

using System;

public interface ITradable
{
    int OriginalValue { get; }
}

public class InventoryItem : ITradable
{
    public int OriginalValue
    {
        get
        {
            return 5;
        }
    }
}

public class Service : ITradable
{
    public int OriginalValue
    {
        get
        {
            return 10;
        }
    }
}

public class Shop <T> where T : ITradable
{
    public int Trade (T trade)
    {
        return trade.OriginalValue;
    }
}

class Program
{
    static void Main(string[] args)
    {
        InventoryItem myItem = new InventoryItem();
        Service myService = new Service();
        Shop<InventoryItem> theInventoryShop = new Shop<InventoryItem>();
        Shop<Service> theServiceShop = new Shop<Service>();

        Console.WriteLine("The shop will pay {0} silver coins for your item.", theInventoryShop.Trade(myItem));
        Console.WriteLine("The shop will pay {0} silver coins for your service.", theServiceShop.Trade(myService));
    }
}