Mir Bot
Mir Bot

Reputation: 27

C# type of variable. (variable)

I have an array of Items:

Item[] ItemsOut;

The problem is I have some derived types Item, like EquipItem. They are in this array too.

I have an AddItem function for both of the Item and EquipItem classes.

Inventory.AddItem(AllRecipes.Recipes[curPage].ItemsOut[i]......);

The idea is that in case my array is of type Item[] so it is always adding Items like normal Item.

My current solution is working and it's:

if (AllRecipes.Recipes[curPage].ItemsOut[i].GetType() == typeof(EquipItem))
{
    Inventory.AddItem((EquipItem)AllRecipes.Recipes[curPage].ItemsOut[i], AllRecipes.Recipes[curPage].ItemsOut[i].number);
}
else
{
    Inventory.AddItem(AllRecipes.Recipes[curPage].ItemsOut[i], AllRecipes.Recipes[curPage].ItemsOut[i].number);
}

But if I have 100500 child classes I will be forced to do 100500 if statements.

How to make this automatic? Something like:

Inventory.AddItem((AllRecipes.Recipes[curPage].ItemsOut[i].GetType())AllRecipes.Recipes[curPage].ItemsOut[i], AllRecipes.Recipes[curPage].ItemsOut[i].number);

or

Inventory.AddItem(AllRecipes.Recipes[curPage].ItemsOut[i] as AllRecipes.Recipes[curPage].ItemsOut[i].GetType(), AllRecipes.Recipes[curPage].ItemsOut[i].number);

I would like to be able to do something like:

Type t = AllRecipes.Recipes[curPage].ItemsOut[i].GetType();
Inventory.AddItem((t)AllRecipes.Recipes[curPage].ItemsOut[i].number);

But it causes a "variable used as a type" error, when I DO NEED to use it as a type. Not variable of course, but its value.

Upvotes: 0

Views: 144

Answers (2)

dcidral
dcidral

Reputation: 257

First off, unless you have two methods named AddItem (one for Item and another for EquipItem) you don't need to cast your ItemsOut, just use Inventory.AddItem(AllRecipes.Recipes[curPage].ItemsOut[i], AllRecipes.Recipes[curPage].ItemsOut[i].number);

Second, you can't do this:

Type t = AllRecipes.Recipes[curPage].ItemsOut[i].GetType();
addItem((t)AllRecipes.Recipes[curPage].ItemsOut[i]

because t is an instance of the class Type, you can only cast using the type name like (EquipItem) AllRecipes.Recipes[curPage].ItemsOut[i]

And finally, unless you are having performance issues, don't ever try to optimize your code. Doing so is what we call Premature Optimization

So, check if you have a method AddItem(EquipItem equipItem). If you don't, you don't need to check it's type and cast the Item to EquipItem. Hope I could help you.

EDIT the best thing I can think that can improve your code is clearing it a bit, like this:

var item = AllRecipes.Recipes[curPage].ItemsOut[i];
if (item is EquipItem)
{
    Inventory.AddItem((EquipItem) item, item.number);
}
else
{
    Inventory.AddItem(item, item.number);
}

Upvotes: 1

Jamiec
Jamiec

Reputation: 136074

The idea here should be not to make anything know the difference between an Item, an EquipItem (or for that matter any old FooItem).

If they all derive from Item and the array is typed as Item[] then those subclasses can be added to the array without issue

var item = new Item();
var equip = new EquipItem(); // where EquipItem inherits from Item;
var array = new Item[]{ item,equipItem}; // no error here

If you have a single AddItem method, which adds to this array and performs some action based on the type, again the calling code should not know anything about the type - perhaps some virtual method which does some action when added to the list

public class Item
{
    public virtual void AddedToList(){}
}    

public class EquipItem
{
    public override void AddedToList()
    {
        // behaviour specific to EquipItem
    }
}

Upvotes: 1

Related Questions