Inventory Programming: Derived Class Issue (C#)

Hello everyone!

I think this might be more of a general programming problem than a Unity one, but I hope some of you fine folk will be able to help me out.

I am working on an inventory and item system for my game. The basic idea at first was to have a base Item class, and then derive the types of items for specific classifications. For example:

Item
Weapon : Item
Shield : Item
Broadsword : Weapon
Iron Shield : Shield

And so on and so forth, this way each item only would have properties it needs and not a bunch of irrelevant information.

But then I run into issues when making my inventory. It would be a list of items:

public List<Item> inventory;
inventory.Add(new Broadsword);
Debug.Log(inventory[0].damage); //ERRORZ as the Item class doesn't have this var

The only idea I have for solving this at the moment is to cast the item back to it’s original type when the information is need, using a variable to determine what to cast to, like so:

if (inventory[0].itemType == "Weapon")
Weapon myWeapon = (Weapon)inventory[0]
Debug.Log(myWeapon.damage) //Huzzah, we have the value!

This seems a bit… inelegant to me. I was wondering if anyone had any other ideas on fixing this particular problem. Also related, I would like to be able to see the derived classes’ public variables in the Inspector when looking at the Inventory script, but currently it would only show fields that Item has. I assume I would need a custom inspector to fix this (or is this fixable at all)?

A few comments before this gets closed for being too general:

You would have a specific master list of Weapon, another of Shield and so forth, where you should be able to see all the variables. Since they are also Items, you can add them to an Item list as you spawn them.

Another way to check itemType is cast then null check: Weapon ww = (Weapon)A; if(A!=null). You have to cast anyway, to look at the weapon properties, so this usually works better.

IronShield would probably not be a subclass of Shield. It would be a type of shield with different stats.

The first time you make real derived classes is usually a learning experience, and needs to be junked after.

Apart from the discussed issues of object oriented design, you might want to consider using “as” for a slightly more elegant access solution (just the last line):

using UnityEngine;
using System.Collections.Generic;
	
public class Baseclass  {
	public int baseVal;
}

public class Derivative : Baseclass {
	public int derVal;
}

public class Inherit : MonoBehaviour {
	
	public List<Baseclass> inventory;
	
	void Start()  {
		inventory = new List<Baseclass>();
		inventory.Add(new Derivative());
		(inventory[0] as Derivative).derVal = 5;
		Debug.Log ("Val ="+(inventory[0] as Derivative).derVal);
	}
}