I have an abstract class Entity
in my code, which requires a reference to an instance of EntityData
to operate. (EntityData
provides basic information about the type of the entity).
In the design of my program, every type of entity would have its own class that extends Entity
, and thus would have to provide EntityData
that would describe and be shared between all of the instances of that that entity class.
EntityData
itself is an immutable class that is built like a multiton (similar to Java's enum). It has a private constructor, and its instances are revealed as readonly static fields.
An example of how EntityData
would look:
sealed class EntityData
{
public static readonly EntityData Table = new EntityData(250, 60);
public static readonly EntityData Chair = new EntityData(120, 25);
public readonly int Cost;
public readonly int Weight;
private EntityData(int cost, int weight)
{
Weight = weight;
Cost = cost;
}
}
I can think of two simple ways to deal with this, but I am uncertain which one I should go with.
First one is to add a reaodnly field to Entity
and request is via the constructor, so Entity
would look like this:
abstract class Entity
{
private readonly EntityData data;
protected Entity(EntityData data)
{
this.data = data;
}
}
While an extending class, Table
for example, would look like this:
sealed class Table: Entity
{
public Table() : base(EntityData.Table) {}
}
The second option would be to add an abstract, protected property (getter only) to Entity
. In this case Entity
would look like this:
abstract class Entity
{
protected abstract EntityData Data { get; }
}
While the extending class Table
would look like this:
sealed class Table : Entity
{
protected override EntityData Data
{
get { return EntityData.Table; }
}
}
Thus internally, Entity
would simply use the property instead of a field.
The performance differences are probably in the realm of micro-optimization, but I would still like to take them into consideration.
The first way obviously increases the size of any Entity
object.
The first way also forces all the extending types to define their constructors and call the base constructor or will simply increase the number of parameters in the already existent constructor.
The second way doesn't increase the size of objects, and (to me) look shorter and slightly more concise.
Performance-wise however, benchmarking showed that a virtual method call is much slower than accessing a field.
It is also less obvious that such a property is a dependency of Entity
, something the first way makes perfectly clear.
As there's no clear-cut answer here, I would simply love to have a few opinions on the matter, and which of the two ways you find 'better'.
Thanks in advance.
(Please no responses about how this is in the realm of micro optimization and thus I shouldn't waste my time with it. I simply find this interesting.)