How to pass type as a parameter in function

Hey guys, so I am creating a general inventory adding function (basically, it receives an input and will create an instance of a script that will be a new weapon in the first slot of the player’s inventory, which is an array of objects). My problem is that, the function is inside the character class and I don’t know how to pass a type as a parameter in this function and end up with an object/instance of that type in the person’s inventory. I’ve tried using System.Type for a parameter, referenced this old thread here (How do I pass an Object type to a function in c#? - Unity Engine - Unity Discussions) which seemed like what I was trying to do but I just can’t get it to work for me, and everything else under the sun. I attached some of my code below to give a better idea of my problem. Any help or a push in the right direction would be immensely appreciated! Thanks guys!

public class BaseCharacterClass {
    // defining everything for every base character (i.e. stats, description, movement allocation, etc.)
protected Object[] characterWeaponInventory = new Object[4];
public Object[] CharacterWeaponInventory
    {
        get
        { return characterWeaponInventory; }
    }


}

And this is the code that is giving me trouble (it’s inside the character class I posted above and references those variables/arrays) (also references item classes that I haven’t included here):

public void AddItemToInventory(Object newAddedItem /* this parameter is the one giving me trouble */)
    {
        if (newAddedItem.GetType().IsAssignableFrom(typeof(BaseItem)))
        {
            if (newAddedItem.GetType().IsSubclassOf(typeof(BaseStatsWeaponItem)) && this.CharacterWeaponInventory.Length < 4)
            {
                int slotToBeAddedTo = this.CharacterWeaponInventory.Length;
                this.CharacterWeaponInventory[slotToBeAddedTo] = newAddedItem;
            }
            if (newAddedItem.GetType().IsSubclassOf(typeof(BasePotion)) || newAddedItem.GetType().IsSubclassOf(typeof(BasePermabuff)) || newAddedItem.GetType().IsSubclassOf(typeof(BasePromotionItem)) || newAddedItem.GetType().IsSubclassOf(typeof(BaseHeldEffectItem)) || newAddedItem.GetType().IsSubclassOf(typeof(BaseLiquidAssetItem)) || newAddedItem.GetType().IsSubclassOf(typeof(BaseKeyItem)) && this.CharacterItemsInventory.Length < 3)
            {
                int otherSlotToBeAddedTo = this.CharacterItemsInventory.Length;
                this.CharacterWeaponInventory[otherSlotToBeAddedTo] = newAddedItem;
            }
        }
    }

I could be wrong, but I think that newAddedItem.GetType() and typeof(BaseItem) should be swapped in line 3 (and your other similar lines.)

You should also be able to do if (newAddedItem is BaseItem) instead, and simplify that code a lot.

Additionally, your array handling is problematic, based on that code. Especially lines 7 and 8.

                int slotToBeAddedTo = this.CharacterWeaponInventory.Length;
                this.CharacterWeaponInventory[slotToBeAddedTo] = newAddedItem;

In some languages, this is how you add an item to an array, but not C# - in C# this will just throw an out of range exception.

You seem to want a group of items that you can add and remove items from, and for that you’ll want to use a List<> rather than a builtin array. Builtin arrays are slightly faster, but can’t be resized; Lists are a lot more versatile, but a tiny bit slower. (The speed won’t matter on this scale; builtin arrays are mostly used for things that can reach into the hundreds or thousands, e.g. vertex arrays on meshes.) The version of the above code, if CharacterWeaponInventory were a List, would be:

this.CharacterWeaponInventory.Add(newAddedItem);

It’s also worth noting that encapsulating your array (protected with a public accessor) as you’ve done there is kind of pointless, since any class can still freely modify the contents of the array - may as well skip a step and just make the thing public. If you want to protect access, then get rid of that accessor and write some AddItem, RemoveItem, FindItem, etc accessor functions. (This is true for both List and a builtin array)

List also has a .ToArray() method that will give you a copy as an Object[ ], if you still need that as an array for any particular reason.

Thanks for the feedback but I think i might not have explained myself well. Im using a 4 element array since i want the inventory to only be able to contain 4 objects and didnt know if you could limit a list’s size without unnecessary extra lines of code. Also, would setting the element of the array equal to the new instance of whatever type is input not add it correctly (2nd block, line 8)? If so, why not? Also, my main problem was just getting the function to recognize a class/type as a parameter which is on line 1 in the second code block, then i want to turn that parameter into a new instance of that class in the function which can be added to the appropriate array index. Thanks in advance, and sorry if I’m not being too clear, I’m not 100% sure of all the official terms to describe what I’m trying to do :slight_smile:

I’m not quite sure what you are needing. But for an inventory system, I would suggest creating an IInventoryItem interface, and have all of your inventory items implement this interface. Then you don’t need to use objects, and have predicable methods and properties for inventory items (like ‘weight’ for example).

And yes, please use generic Lists, such as:

List<IInventoryItem> InventoryList = new List<IInventoryItem>();

And to answer your question, here’s how you could pass an inventory item type to a function to delete it from inventory:

DeleteItem(typeof(InventoryItemBanana));
public void DeleteItem(Type t) {
   foreach (IInventoryItem item in InventoryList) {
       if (item.GetType() == t) {
           Items.Remove(item);
           return;
       }
   }
}
1 Like