using static MagicHappensHere;
public static void Main()
CanEquip(new Titan(), new ArtifactSlot(), new Artifact());
CanEquip(new Warlock(), new ArtifactSlot(), new Artifact());
CanEquip(new Warlock(), new ArtifactSlot(), new Spellbook());
CanEquip(new Warlock(), new WeaponSlot(), new Staff());
CanEquip(new Titan(), new ArtifactSlot(), new Spellbook());
CanEquip(new Titan(), new WeaponSlot(), new Staff());
public class Warlock : Hero {}
public class Titan : Hero {}
public class WeaponSlot : Slot {}
public class ArtifactSlot : Slot {}
public class Weapon : Item {}
public class Sword : Weapon {}
public class Staff : Weapon {}
public class Artifact : Item {}
public class Spellbook : Artifact {}
public static class MagicHappensHere
public static void CanEquip(Hero hero, Slot slot, Item item)
var result = Equippable(hero as dynamic, slot as dynamic, item as dynamic);
var action = result ? "can" : "can't";
Console.WriteLine($"{hero.GetType().Name} {action} equip {item.GetType().Name} in {slot.GetType().Name}");
public static bool Equippable(Hero hero, Slot slot, Item item) => false;
public static bool Equippable(Hero hero, ArtifactSlot slot, Artifact item) => true;
public static bool Equippable(Warlock hero, ArtifactSlot slot, Artifact item) => false;
public static bool Equippable(Warlock hero, ArtifactSlot slot, Spellbook item) => true;
public static bool Equippable(Warlock hero, WeaponSlot slot, Staff item) => true;
public static bool Equippable(Hero hero, ArtifactSlot slot, Spellbook item) => false;
public static bool Equippable(Hero hero, WeaponSlot slot, Staff item) => false;