0

I am using c# language for unity.

I need to use parent-child class for inventory system.

My script concept is below.

and i have error always at i marked it.

I know virtual-override can fix this thing but i just want to know that

Is this possible to use this concept?

public class A
{
    public int a;
}

public class B : A
{
    public int b;
}

public class C : A
{
    public int c;
}


public class Main<T> where T : A, new()
{
    public void callValue(T item)
    {
        if (item is B)
        {
            Console.WriteLine(item.a + "||" + ((B)item).b); // error cannot convert T to B;
        }
        if (item is C)
        {
            Console.WriteLine(item.a + "||" + ((C)item).c);
        }
    }
}
Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Natejin
  • 55
  • 9

3 Answers3

2

You're so very close in your code. You can do if (item is X x_item) and then use x_item as type X. So like this:

public class Main<T> where T : A, new()
{
    public void callValue(T item)
    {
        if (item is B b_item)
        {
            Console.WriteLine(item.a + "||" + b_item.b);
        }
        if (item is C c_item)
        {
            Console.WriteLine(item.a + "||" + c_item.c);
        }
    }
}

But that seems very weird to have a generic method like that.

I could, for example, do this:

public class D : A
{
    public int d;
}

And then this:

    var m = new Main<D>();
    m.callValue(new D());

If that's the case, what's the point of trying to cast to B or C?

You've got a bad design here.

Enigmativity
  • 113,464
  • 11
  • 89
  • 172
  • This code is perfectly worked for me Thank you. And I am trying to build multi Inventories which can store Equipment, useable, material and other. So each inventory need to check item type that item type can be stack or not. cause if dont need to stack item, just found empty slot and add it. But If not, Check item each slot and just add amount. That is why i need separate methods to depend with item type I will write more detail code in answer for you – Natejin Apr 10 '20 at 22:53
  • @Natejin - You are using inheritance in a way that's going to get you stuck. It's probable that using an `IStackable` interface is probably a better choice. – Enigmativity Apr 11 '20 at 03:08
0

This is my code for use;

public class ItemType
{
    public int ID;
}

public class UnstackableItem : ItemType
{

}

public class Equipment : UnstackableItem {
    public int durability;
}

public class StackableItem : ItemType
{
    public int amount;
}

public class Useable : StackableItem { 

}

public class Material : StackableItem { 

}
public class D : ItemType
{
    public int d;
}

public class Main<T> where T : ItemType, new()
{
    List<T> items;
    Dictionary<int, int> stackCheck;

    public void AddItem(T item, int amount)
    {
        if (item is StackableItem)
        {
            StackableItem(item, amount);
        }
        if (item is UnstackableItem)
        {
            UnStackableItem(item);
        }
    }

    public void UnStackableItem(T item) {
        if (item is StackableItem)
        {
            items.Add(item);
        }

    }

    public void StackableItem(T item, int amount)
    {
        if (stackCheck.ContainsKey(item.ID))
        {
            var itemFrominventory = items[stackCheck[item.ID]];

            if (itemFrominventory is StackableItem unstackItem)
            {
                unstackItem.amount += amount;
            }
        }
        else
        {
            //find empty Slot return value is emptySlotID
            items.Add(item);
            stackCheck.Add(item.ID, emptySlotID);
        }
    }
}
Natejin
  • 55
  • 9
  • My question I posed in my answer wasn't very clear. I was really trying to ask why do `class Main where T : ItemType, new()` when `class Main { public void AddItem(ItemType item, int amount) {} }` would suffice. What's the point of making `Main` generic? – Enigmativity Apr 11 '20 at 03:06
  • @Enigmativity - Because i need to save inventory data through BinaryFormatter. Therefore, the data must be serialize. If i just use Main class, and save it. I will lose durability variable in Equipment class or amount in stackable Item. So I need to make Main<>(or Inventory<>) to make each type of inventory and save it. So i can load all my data. If you have another Idea or want to see my code, tell me please. – Natejin Apr 11 '20 at 07:08
  • No, I don't think you do. From memory, the `BinaryFormatter` will save the concrete type of your object regardless of the run-time type you have a reference to. – Enigmativity Apr 11 '20 at 07:12
  • Oh json is not save type but binaryFormatter is work without use generic Thanks man ^^ – Natejin Apr 11 '20 at 08:16
  • What? "Oh json is not save type but binaryFormatter is work without use generic" – Enigmativity Apr 12 '20 at 02:33
-1

Update those lines to use as instead of an explicit cast:

Console.WriteLine(item.a + "||" + (item as B).b);

Console.WriteLine(item.a + "||" + (item as C).c);
KingOfArrows
  • 556
  • 2
  • 11