Let’s say I have an abstract generic class and a descendant:
public abstract class AuditObject<T> : ActiveRecordBase<T>;
(yes I’m using ActiveRecord) and
public class Employee : AuditObject<Employee>
In both of them I define some static Methods, e.g.
public static DataTable GetLookupTable(String where, Int32 topRows)
{
return doExtremelyCleverStuffToFetchData(where, topRows);
}
(in the Employee class you need public new static or else you get a compiler warning)
As the code is, when I call e.g.
DataTable myList = AuditObject<T>.GetLookupTable("inactive = 0", 100);
…and T is Employee, the static method is not “overriden” i.e. the one that is executed is the method in AuditObject, not Employee .So in AuditObject I modified the static methods (in this example, GetLookupTable) like this :
public static DataTable GetLookupTable(String where, Int32 topRows)
{
DataTable tbl = null;
Boolean hasOverride = hasMethodOverride("GetLookupTable");
if (hasOverride)
{
tbl = invokeStaticMethod<T>("GetLookupTable", new Object[2] { where, topRows }) as DataTable;
}
else
{
tbl = doExtremelyCleverStuffToFetchData(where, topRows);
}
return tbl;
}
Here’s how I find out if the static method exists :
private static Boolean hasMethodOverride(String methodName)
{
var methodQuery =
from method in typeof(T).GetMethods(
BindingFlags.Static | BindingFlags.Public | BindingFlags.InvokeMethod)
where method.Name == methodName
select method;
return methodQuery.Count() > 0;
}
And here’s how the “override” method is called :
public static Object invokeStaticMethod<T>(String MethodName, Object[] Args)
{
return typeof(T).InvokeMember(MethodName,
BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod,
null, null, Args);
}
Voila ! When I call, say, DataTable myList = AuditObject<T>.GetLookupTable(“inactive = 0”, 100); and T is Employee, I get results from the static method defined in the Employee class.