I am working on an ORM for a Windows CE device. I need to cache getter/setter methods of properties as delegates and call them when needed for best perfromance.
Lets say I have 2 entities defined like this:
public class Car
{
public string Model { get; set; }
public int HP { get; set; }
}
public class Driver
{
public string Name { get; set; }
public DateTime Birthday { get; set; }
}
I need to be able to hold 2 delegates for each property of each entities. So I create a AccessorDelegates class to hold 2 delegates for each property:
public class AccessorDelegates<T>
{
public Action<T, object> Setter;
public Func<T, object> Getter;
public AccessorDelegates(PropertyInfo propertyInfo)
{
MethodInfo getMethod = propertyInfo.GetGetMethod();
MethodInfo setMethod = propertyInfo.GetSetMethod();
Setter = BuildSetter(setMethod, propertyInfo); // These methods are helpers
Getter = BuildGetter(getMethod, propertyInfo); // Can be ignored
}
}
Now I want to add each AccessorDelegates for a specific entity type into a list. So I defined a class:
public class EntityProperties<T>
{
public List<AccessorDelegates<T>> Properties { get; set; }
}
I need to hold these EntityProperties for each entity type, in my example Car and Driver. I created a Dictionary<string, EntityProperties<T>> string representing entity name just for simplicity for now:
public class Repo<T>
{
public Dictionary<string, EntityProperties<T>> EntityPropDict { get; set; }
}
This is where I cannot find a solution to my problem. I want to hold EntityProperties for each entity type but I have to give Repo<T> class a type parameter to be able to create the dictionary (because EntityProperties<T> requires a type parameter).
I need to be able to create it without a type parameter as Repo only. How can I define a Dictionary<string, EntityProperties<T>> without giving my Repo class a type parameter?
I’ve come to a solution, a little smart code but works fine.
I added an interface to be implemented by AccessorDelegates:
I changed my PropertyMetadata to contain an IAccessorDelegate instead of AccessorDelegate:
Now, I can create and initialize an AccessorDelegate this way:
PropertyMetadata.GetAccessorDelegates<T>()method enables me to cast and get the object in actualAccessorDelegate<T>type.