I've stumbled upon the need to do this a few times recently with some lower level framework type stuff and I'd like to see if there is a better/cleaner way to accomplish this, i.e. if I'm missing something obvious or clever, like the time I discovered [ThreadStatic]
to replace dictionary lookups against thread IDs for associating data with Threads.
I have a base abstract class, lets call it Entity
. Every Entity
needs to perform a set of initialization actions in the constructor that depends on the actual concrete class being instantiated. Is there a way I can accomplish this without doing a dictionary lookup and calling this.GetType()
?
Here is some code similar to what I have now:
public abstract class Entity
{
private static Dictionary<Type, Action<EntityData>> _initActions = new Dictionary<Type, Action<EntityData>>();
private EntityData _data = new EntityData();
protected Entity()
{
_initActions[this.GetType()].Invoke(_data);
}
}
public class Employee : Entity
{
public string Name { get; set; }
}
public class Manager : Employee
{
public List<Employee> Subordinates { get; set; }
}
The Employee
constructor and Manager
constructor need to initialize their _data
fields differently as they are different types. The _initActions collection gets initialized in another method prior to any instances being new'd up, which I don't think has any significance on this discussion.
I want usage of the class to remain as simple as possible for the user of the framework, so I can't use strange hacks like requiring users to override an Init method in each concrete type in some peculiar or unintuitive way.
Generics almost work, in the sense that I could do something like Entity<TEntity>
to get a TEntity specific static field to store the init method if I didn't have any inheritance, but inheritance needs to be supported so I would need a dictionary of all init methods for the subclasses of TEntity anyway.
This code runs in some pretty low level database engine type scenarios in tight loops with 1m iterations, so getting rid of the dictionary lookup does provide some significant speedups in certain situations (tested by replacing with a hacky Init override implementation).
Any ideas?
EDIT:
I want to make a few things clear. The entity engine automatically sets up _initAction to do what it needs to to initialize its _data container. The "user" of the library knows nothing about this process and doesn't need to. All I was inquiring about is a way to avoid a dictionary lookup to get type-specific runtime information from a base class, but that may not be possible.
Yes, this is micro-optimization, but we have tested this with real queries and gotten 15-20% query time reductions on some queries that need to instantiate large datasets.
The faster code looked like this:
public class Employee : Entity
{
private static EntityInitializer _initMethod = Entity.GetInitMethod(typeof(Employee));
public string Name { get; set; }
public Employee()
{
_initMethod.Invoke(this);
}
}
This way, the dictionary lookup is done once for the Employee type. It's not horrible, but it requires a) boilerplate in every single class, which I don't like and b) slightly error prone as you have to match up the type parameter with the current class otherwise funky things happen, kind of like when you type in the wrong owner class name for a dependency property in WPF. Kinda sometimes works, but then wierd bugs pop up and its hard to trace back.
What it comes down to is this: is there was a better way to attach arbitrary runtime data to a Type besides using a Dictionary, considering that all these types that will have this data attached to them all implement a common base class?