How can I check if a class overrides a particular method, based string of the class name?
I have a base class called FormBA. Several classes extend this class following the name scheme of Form_XXXX_BA
(where XXXX
is the abreviated name of the form). Given the abreviated name of the form, I need to check to see if it overrides one particular method (I can tell based on the output of the method, if need be)
Some things worth noting:
- Not all forms have an
Form_XXXX_BA
, but I want to have to edit my c开发者_高级运维ode if one is added. - The method I am checking is static, however, it takes a
Form_XXXX_BA
class as a parameter.
I've looked at Activator.CreateInstance
and System.Reflection
, but I have not been able to wrap my head around how they would help (although they may vary well be the solution, I just don't understand them).
EDIT: Yes, by extends a method I did mean overrides, my bad. Fixed.
Thanks for your help so far and sorry I wasn't clear on my issue, although it looks like sixlettervariables may be on the right track.
I have a bunch of forms on the system. For some forms, the user is able to eMail them to another user. Currently there is a default message for all the forms (FormsBA.getEmailBody(FormsBA) ). The ones that are currently sendable override this method so set the body based on the form itself. (example, for Form ABC - Form_ABC_BA.getEmailBody(Form_ABC_BA) )
Now the issue is, there is now an admin panel to enable/disable emailing for each seperate form.If a Form doesn't have this custom body and an Admin wants to enable emailing, I want to display a message warning the admin that the message will not be the full form as they are used to, and to contact development to create this body. I would like to make this work in such a way that I don't have to update my code if a new email body, or even a new form altogether is created.
There are 3 situations that I would like to account for:
-Form_ABC_BA.getEmailBody(Form_ABC_BA) exists, therefore overriding the FormsBA method.
-Form_ABC_BA exists but the getEmailBody(Form_ABC_BA) does not exist, therefor the method in FormsBA is used for this form
-Form_ABC_BA does not exist, therefor the method in FormsBA is used
It is tough to tell exactly what you're attempting to solve, but one approach (which assumes you want to find a derived class with with a given name that has a static method taking the same derived class as an argument):
var formName = String.Format("Form_{0}_BA", name);
var candidate = typeof(FormBA).Assembly
.GetTypes()
.Single(tt => tt.IsSubclassOf(typeof(FormBA))
&& tt.Name.EndsWith(formName));
var method = candidate.GetMethods(BindingFlags.Static | BindingFlags.Public)
.Single(mi => mi.GetParameters()
.Single()
.ParameterType == candidate);
If I understand your question correctly - Then you can use Type.GetMethod
specifying BindingFlags.DeclaredOnly
. That will return the methods that are specifically declared in your specific class - if this includes your base method, then the specifc class overrides your base method. You can also check on whether the method is virtual, to ensure that it actually overrides the base class method - to guard against the case when a developer has hidden the orignal method using the new
keyword instead of overriding it.
public bool IsOverridden(string methodName, Type baseType, Type specificType)
{
var baseMethod = baseType.GetMethod(methodName);
var method = specificType.GetMethod(methodName, BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance);
return baseMethod != null && method != null && method.IsVirtual;
}
You can only tell if a class overrides a virtual method. I'll assume you already know if a particular type derives from another (otherwises use rerun's example or use Console.WriteLine(typeof (Base).IsAssignableFrom(typeof(Derived)))
If you want to see if particular type declares (or overrides a virtual) method, you can use Type.GetMethods
to search for methods of a given name. for example, if you have a virtual method named "b2" you can tell if a particular type declares that method as follows:
typeof(MyType).GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance).Any(m => m.Name == "b2")
I think I've mis-understood your question. You're not "extending" anything with a static member.
I think what you're asking is whether you can tell if a class has a static method that takes a paricular type for an parameter. You can do that by iterating all the method then iterating all their parameters looking for a parameter of a particular type. for example:
if I want to see if a type SomeType has a method that takes a parameter of type FormType, I could do the following:
typeof(SomeType).GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Static).Any(m => m.GetParameters().Any(p=>typeof(FormType).IsAssignableFrom(p.ParameterType)))
Interesting question. In OO terms you do not want to know HOW a class handles a request. So "knowing" whether a method is overridden should not matter.
Now for a solution. If knowing whether a method is overridden you could take the easy way: Create a readonly overridable boolean property in the base class like "IsMethodXOverriden" and set it to false. In the classes that do override the method you can also override this boolean and set it to true.
public virtual class MyBaseClass
{
public virtual boolean IsMethodXOverridden { get { return false; } }
public virtual void MethodX()
{
DoSomething();
}
}
public sealed class MySuperClass : MyBaseClass
{
public override bool IsMethodXOverridden { get { return true; } }
public override void MethodX()
{
DoSomethingElse();
}
}
精彩评论