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.