Mini RPG equipment code what do you think about this code? It's upgraded version of: 
Classes representing items in an RPG game

using System;
using System.Collections.Generic;

public class Item
{
    public string Name { get; protected set; }
    public int Cost { get; protected set; }

    public override string ToString()
    {
        return "Name: " + Name + "\nCost: " + Cost;
    }

    public Item(string name, int cost)
    {
        Name = name;
        Cost = cost;
    }
}

public abstract class SpecialItem : Item
{
    public virtual int GetSpecialProperty { get; }
    public override string ToString() { return base.ToString() + "\nDamages/ArmorPts/HungryRestorePts: " + GetSpecialProperty; }
    public SpecialItem(string name, int cost) : base(name, cost) { }
}

public abstract class ElementalsItem : SpecialItem
{
    public int Fire  { get; protected set; }
    public int Water { get; protected set; }
    public int Earth { get; protected set; }
    public int Wind  { get; protected set; }
    public override string ToString()
    {
        return base.ToString()
            + "\nFire Damages/Resistance: " + Fire
            + "\nWater Damages/Resistance: " + Water
            + "\nEarth Damages/Resistance: " + Earth
            + "\nWind Damages/Resistance: " + Wind;
    }
    protected ElementalsItem(string name, 
                             int cost,
                             int fire, 
                             int water,
                             int earth, 
                             int wind)
                             : base(name, cost)
    {
        Fire  = fire;
        Water = water;
        Earth = earth;
        Wind  = wind;
    }
}

public class Weapon : ElementalsItem
{
    public int Damages { get; private set; }
    public override int GetSpecialProperty { get { return Damages; }}
    public override string ToString() { return base.ToString(); }

    public Weapon(string name,
                  int cost,
                  int damages,
                  int fireDamages  = 0,
                  int waterDamages = 0, 
                  int earthDamages = 0,
                  int windDamages  = 0)
                  : base(name, cost, fireDamages, waterDamages, earthDamages, windDamages)

    {
        Damages = damages;
    }
}

public class Armor : ElementalsItem
{
    public int ArmorPts { get; private set; }

    public override int GetSpecialProperty { get { return ArmorPts; }}
    public override string ToString() { return base.ToString(); }

    public Armor(string name,
                 int cost,
                 int armorPts,
                 int fireResistance  = 0,
                 int waterResistance = 0,
                 int earthResistance = 0,
                 int windResistance  = 0) 
                 : base(name, cost, fireResistance, waterResistance, earthResistance, windResistance)
    {
        ArmorPts = armorPts;
    }
}

public class Food : SpecialItem
{
    public int HungryRestorePts { get; private set; }
    public override int GetSpecialProperty { get { return HungryRestorePts; }}
    public override string ToString() { return base.ToString(); }

    public Food(string name, int cost, int hungryRestorePts) : base(name, cost)
    {
        HungryRestorePts = hungryRestorePts;
    }
}

class Equipment
{
    public static void Test()
    {
        List&lt;Item&gt; items = new List&lt;Item&gt;();
        items.AddRange(new Item[] { new Item("Stone", 1),
                                    new Armor("Steel Helmet", 80, 10),
                                    new Weapon("Great Sword", 120, 80),
                                    new Armor("Storm Cuirass", 1000, 120, 0, 0, 0, 60),
                                    new Weapon("Fire Spear", 1400, 60, 0, 80, 0, 0),
                                    new Food("Apple", 5, 10) });
        foreach(Item i in items)
        {
            Console.WriteLine(i.ToString());
            Console.WriteLine();
        }
    }
}
Edge cases are where such class hierarchies often fall short.


An offhand short sword that adds to defense?
A shield that does damage when you bash with it?
A magic potion that not only makes you less hungry but also adds
armor when you drink it?


How will those fit into your current hierarchy? One way to avoid those problems is to use aggregation instead of inheritance and treat each game object as a collection of arbitrary properties, that can be added to object or removed from it. You might want to look at how, for example, things are done in Unity, to get a better understanding of how things are actually designed in modern engines.

To be clear, there is nothing wrong with having game object hierarchies in small projects. It is the easiest approach and sometimes it is enough, especially if all you want is to write some code. I just wanted to give you some perspective.

EDIT
Since this question is getting a lot of attention I though I might as well update my answer with a simplified example.

First, you have to create some "components". For the sake of this example, you can think of components as properties that define the item and make it different and special. What is a fire sword? It is an item that:


people in the village call "Lightbringer"
requires some "sword" skill to use
looks like a big burning knife
can do slicing damage to things
but does fire damage too
it weights 8 kg
it costs 1000g and can be bought or sold
etc...


Those are the aspects of a fire sword that make it what it is. And every one of those aspects can be defined as separate component.

abstract class ItemComponent
{
    //What goes into base class entirely depends 
    //on how your game engine is implemented.
    //I left it out because it is irrelevant 
    //in context of this example
}

class Valuable : ItemComponent
{
    public int Cost { get; set; }

    public override string ToString()
    {
        return "It is a valuable item, that can be bought for " + Cost + "g.";
    }
}

class PhysicalDamage : ItemComponent
{
    public int Slashing { get; set; }
    public int Bashing { get; set; }
    public int Piercing { get; set; }

    public override string ToString()
    {
        return String.Format("It does {0}/{1}/{2} physical damage.", Slashing, Bashing, Piercing);
    }
}

class ElementalDamage : ItemComponent
{
    public int Fire { get; set; }
    public int Water { get; set; }
    public int Earth { get; set; }
    public int Wind { get; set; }

    public override string ToString()
    {
        return String.Format("It does {0}/{1}/{2}/{3} elemental damage.", Fire, Water, Earth, Wind);
    }
}

//etc...


And this is a typical game object that theoretically can represent anything from a stone on the ground to a bullet. It's just a collection of arbitrary components.

class Item
{
    public Item(string name)
    {
        Name = name;
    }
    //Name can be a component too! 
    public string Name { get; private set; }

    public Item AddComponent(ItemComponent component)
    {
        _components.Add(component);
        return this;
    }

    public T GetComponent&lt;T&gt;()
    {
        return (T)_components.OfType&lt;T&gt;().FristOrDefault();
    }

    public override string ToString()
    {
        var sb = new StringBuilder();
        sb.AppendLine(Name);
        _components.ForEach(c =&gt; sb.AppendLine(c.ToString()));
        return sb.ToString();
    }

    private List&lt;ItemComponent&gt; _components = new List&lt;ItemComponent&gt;();
}


Then to create a fire sword all you need to do is create an item with all the necessary aspects:

var fireSword = new Item("Lightbringer")
                   .AddComponent(new Valuable { Cost = 1000 })
                   .AddComponent(new PhysicalDamage { Slashing = 10 })
                   .AddComponent(new ElementalDamage { Fire = 10 })
//Maybe it also makes you weak to water attacks? 
//No problem, just define and add new component
                   .AddComponent(new ElementalResistance { Water = -10 };
Console.WriteLine(fireSword.ToString())


This allows you to do all sorts of neat stuff later on. For example, to calculate total resistances of a player, you can call GetComponent&lt;ElementalResistance&gt;() for every equipped item and sum the result.