Check if a method has been overridden?

A

Allan Ebdrup

I'm writing some code where I have have a class that implements 4 methods
(class A)
I only want to call these methods from the base class if they have been
overridden in a sub class (Class B) I guess I could have some properties
that specify wether to call the methods, but I would like to call them
automatically when they are overridden, how do I do this using reflection?

Class A
{
private void methodX()
{
//some code
calculate bool a and call methodY if it has been overridden
calculate bool b and call methodZ if it has been overridden
//some code
}

public virtual void methodY(bool a)
{
//empty
}

public virtual void methodZ(bool b)
{
//empty
}
}

public class B : A
{
override void methodY(bool a)
{
//some code
}
}

so when an instance of class B has methodX called I want it to calculate
bool d and call methodY

Bool a and b are complex to calculate so I don't want to calculate them
unless I need to

Kind Regards,
Allan Ebdrup
 
H

Hans Kesting

I'm writing some code where I have have a class that implements 4 methods
(class A)
I only want to call these methods from the base class if they have been
overridden in a sub class (Class B) I guess I could have some properties that
specify wether to call the methods, but I would like to call them
automatically when they are overridden, how do I do this using reflection?

Class A
{
private void methodX()
{
//some code
calculate bool a and call methodY if it has been overridden
calculate bool b and call methodZ if it has been overridden
//some code
}

public virtual void methodY(bool a)
{
//empty
}

public virtual void methodZ(bool b)
{
//empty
}
}

public class B : A
{
override void methodY(bool a)
{
//some code
}
}

so when an instance of class B has methodX called I want it to calculate bool
d and call methodY

Bool a and b are complex to calculate so I don't want to calculate them
unless I need to

Kind Regards,
Allan Ebdrup

Can't you redesign it so that MethodY doesn't have a parameter, but
instead should get "bool a" through a protected method in that class?
This method can perform the complex calculation, *if* it is called.

This way you can (from MethodX) always call MethodY. If it's not
overridden, it will return quickly.

Hans Kesting
 
B

Barry Kelly

Allan Ebdrup said:
I'm writing some code where I have have a class that implements 4 methods
(class A)
I only want to call these methods from the base class if they have been
overridden in a sub class (Class B) I guess I could have some properties
that specify wether to call the methods, but I would like to call them
automatically when they are overridden, how do I do this using reflection?

The check for whether or not they have been overridden will be
relatively expensive. You'll want to cache the info somewhere.

The way to get the exact information you're after is to call
GetType().GetMethod(...) to get a MethodInfo, and check to see if the
DeclaringType is equal to the base type. If it isn't, then it's
overridden. For example:

---8<---
using System;
using System.Reflection;

class Program
{
class A
{
public virtual void Foo() { }
public virtual void Bar() { }
}

class B : A
{
public override void Foo() { }
}
static void Main(string[] args)
{
B b = new B();
MethodInfo foo = b.GetType().GetMethod("Foo");
MethodInfo bar = b.GetType().GetMethod("Bar");
Console.WriteLine(foo.DeclaringType);
Console.WriteLine(bar.DeclaringType);
}
}
--->8---
Bool a and b are complex to calculate so I don't want to calculate them
unless I need to

Why not put them both as properties in some inner class (say
ExpensiveArguments.A and .B) and have them evaluate on demand, in a
call-by-name way? If you're using C# 2.0, you could pass in anonymous
delegates so that the values get calculated in the context of the
caller. This is what I would do.

It would also give an opportunity to the overriders to avoid evaluating
the expensive arguments if they don't need one or both of them.

-- Barry
 
A

Allan Ebdrup

Hans Kesting said:
Can't you redesign it so that MethodY doesn't have a parameter, but
instead should get "bool a" through a protected method in that class? This
method can perform the complex calculation, *if* it is called.

This way you can (from MethodX) always call MethodY. If it's not
overridden, it will return quickly.

If I could I would reorganize, but we hav a lot of code that already
implements methodY and methodZ, and I can't refactor all that code, at least
not at the moment. It might be don later as part of refactoring. But for now
I can't change MethodY and MethodZ's signatures and functionality.

Kind Regards,
Allan Ebdrup
 
J

Joanna Carter [TeamB]

"Allan Ebdrup" <[email protected]> a écrit dans le message de (e-mail address removed)...

| I'm writing some code where I have have a class that implements 4 methods
| (class A)
| I only want to call these methods from the base class if they have been
| overridden in a sub class (Class B) I guess I could have some properties
| that specify wether to call the methods, but I would like to call them
| automatically when they are overridden, how do I do this using reflection?

Calling empty virtual methods is the easiest and fastest way; using
reflection is usually slower. Why try to circumvent how polymorphism already
works ?

This is known as the Template Method pattern. Simply call the base method in
the assurance that if it is overridden, the derived class's code will be
called, otherwise nothing will happen.

Joanna
 
B

Barry Kelly

Joanna Carter said:
Calling empty virtual methods is the easiest and fastest way; using
reflection is usually slower. Why try to circumvent how polymorphism already
works ?

It's the arguments that are expensive, not the method call, as I
understand it.

-- Barry
 
A

Allan Ebdrup

I'll try this:
private bool isMethodOverridden(string strMethodName)

{

return this.GetType().GetMethod(strMethodName,

System.Reflection.BindingFlags.Public).DeclaringType != typeof(A);

}
 
A

Allan Ebdrup

Barry Kelly said:
It's the arguments that are expensive, not the method call, as I
understand it.

That's correct.
If I could I would reorganize, but we hav a lot of code that already
implements methodY and methodZ, and I can't refactor all that code, at least
not at the moment. It might be done later as part of refactoring. But for
now
I can't change MethodY and MethodZ's signatures and functionality.

Kind Regards,
Allan Ebdrup
 
K

Kevin Yu [MSFT]

Hi Allan,

I agree with Barry, and I think you code will be working fine. However, as
Barry mentioned, using Reflection will cause some performance hit in your
app. This is a disadvantage. Since you have implemented MethodY, it seems
to be the only way.

If anything is unclear, please feel free to post in the community.

Kevin Yu
Microsoft Online Community Support

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.
Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================

(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top