Given the following classes:
public class Item
{
public int id;
public ItemStats s;
public Item(int id)
{
this.id = id;
s = AllStats.Dict[id];
}
}
public class Derived : Item
{
public DerivedStats s;
public Derived(int id) : base(id)
{
s = (DerivedStats)AllStats.Dict[id];
}
}
public class ItemStats
{
public int stat1;
public int stat2;
}
public class DerivedStats : ItemStats
{
public int stat3;
}
static public class AllStats
{
public static Dictionary<int, ItemStats> Dict =
new Dictionary<int, ItemStats>();
}
Run with this:
public class Test
{
static void Main(string[] args)
{
AllStats.Dict[0] = new ItemStats(); // initialize stats for id 0
ItemStats s = AllStats.Dict[0];
s.stat1 = 1;
s.stat2 = 2;
AllStats.Dict[1] = new DerivedStats(); // initialize stats for id 1
DerivedStats d = (DerivedStats)AllStats.Dict[1];
d.stat1 = 1;
d.stat2 = 2;
d.stat3 = 3;
Item I = new Item(0); // item with id 0
Derived D = new Derived(1); // derived with id 1
Console.WriteLine(I.s.stat1);
Console.WriteLine(D.s.stat3);
}
}
The purpose is to have all statistics for these items in a static dictionary, because they don't need to be included as fields in every single item instance, since they are the same for all instances.
But the derived items can have different stats (additional fields in the statistics), so I have a derived type also for the ItemStats
class.
The program runs, but I get a warning that s
in Derived
class is hiding s
from the base class. The warning goes away if I use the new
keyword but I lose polymorphism and I don't know if it can have bad consequences at runtime.
This works without warnings:
public class Item
{
public int id;
ItemStats _stats;
public virtual ItemStats s => _stats;
public Item(int id)
{
this.id = id;
_stats = AllStats.Dict[id];
}
}
public class Derived : Item
{
DerivedStats _stats;
public override DerivedStats s => _stats;
public Derived(int id) : base(id)
{
_stats = (DerivedStats)AllStats.Dict[id];
}
}
The only issue I have with this solution is that it uses a property, that is an additional function call every time I access it (and it's pretty often), so I assume it's slower than just accessing s
as a field.
So I'm looking for a solution that is both as performant as possible and that doesn't cause warnings, field hiding and loss of polymorphism. Ideal would have been if it was possible to use virtual
and override
for a class field, but it doesn't compile.