10

Is it possible to call a protected method via reflection. I am using this:

 Me.GetType.InvokeMember(Stages(CurrentStage), Reflection.BindingFlags.InvokeMethod, Nothing, Me, Nothing) 

Which always calls a method with no params or return. The idea is that the user of my object (transactional processing of business logic) inherits the base class adds in a load of private methods to fire. They then add these method names to a list in the order they would like them fired and the code above will take care of firing them.

It works fine with public methods but not with private or protected methods in the same class (Protected because I have some 'standard' pre built methods to add to the base class). Realistically I could make the methods public and be done with it but my inner nerd wont allow me to do so...

I am assuming this is a security feature. Is there a way to get around this or does anyone have any suggestions on how to proceed but keep my tasty, tasty visibility modifiers in tact?

(NOTE: ITS IN VB.NET but a C# Answer is fine if that is what you are comfortable with).

3 Answers 3

13

If you are invoking the methods on an instantiated object, you will also need BindingFlags.Instance. So the code would look like (Note: I've also added the BindingFlags option to include public members in the search):

Me.GetType.InvokeMember(Stages(CurrentStage), BindingFlags.InvokeMethod Or BindingFlags.NonPublic Or BindingFlags.Public Or BindingFlags.Instance, Nothing, Me, Nothing) 

For more information on how to use this, refer to the MSDN Documentation.

EDIT

To support this answer, I have written a test program that demonstrates the invocation of public, protected and private class methods. I have uploaded all classes to PasteBin. There are three classes that make up a C# Console Application, so can be added to a Visual Studio solution and run to test.

  • Program.cs - Sets up the methods to be invoked (contained within the SomeClass class). Executes the invocation and prints the results.
  • SomeClass.cs - Contains three methods of each of the visibility modifiers: public, protected and private. Also registers itself and the three contained methods for invocation by the Invoker class.
  • Invoker.cs - Accepts registration of types and methods that are to be invoked. Then enumerates the registered types and invokes the methods, building an enumerable collection of results.

Feel free to look over that code and see if you can find any differences in how you are approaching it. I appreciate it may not be the simplest of approaches, though. Let me know if you have any further queries on it.

Sign up to request clarification or add additional context in comments.

5 Comments

This works, although it only finds protected and not private, either way I am happy with that.
It should find private too - I have written a simple test app that confirms that.
Hmmm, It won't work for me... The only change is changing from protected to private...
Cheers, Reading through your code I don't seem to be missing anything. I might remove any sensitive data and post this a separate question. Thanks for the extended info.
I posted a new question on this as a sub problem as it may be my implementation as opposed to just missing a binding flag. stackoverflow.com/questions/8746221/…
5
+100

You might not need reflection for this. Maybe I misunderstood what you wanted to achieve but it sounds like you want to inject a bunch of methods to another method, kinda wrap them. You can pass in the private methods as delegate params. Something like this:

public class Base { protected virtual void Execute(IList<Action> actions = null) { actions = actions ?? new List<Action>(); // do stuff like begin tran foreach (var action in actions) { action(); } // do stuff like end tran } } public class Sub : Base { protected override void Execute(IList<Action> actions = null) { actions = actions ?? new List<Action>(); actions.Add(A); actions.Add(B); base.Execute(actions); } private void A() { } private void B() { } } 

Sub's Execute will call the code you wrote in Base then it will execute A then B and finally everything you declared after the for each in Base.

5 Comments

That's a really nice implementation. As a thank you I'm going to award you with 100 bounty points when the question allows it. (2 Days) Cheers for the sample.
I had to make some minor changes to make it work but this is a great example, fair play! Works a charm!
I have create the bounty for you and will be able to reward it in 1 Day :)
thank you. I really appreciate it. C# is pretty cool and delegates can be used for stuff like this. I am glad the solution worked for you. :)
No Problem, Actually I am using VB.Net (Legacy Solution) but I agree the C# Version is much prettier than the resulting VB, Maybe I am just biased to C based languages though :)
2

Use the NonPublic member from BindingFlags to include all the methods in your class:

Me.GetType.InvokeMember(Stages(CurrentStage), BindingFlags.InvokeMethod Or BindingFlags.NonPublic, Nothing, Me, Nothing) 

2 Comments

Hmmm, It still doesn't seem to work.... The only change I have made is to replace the | with 'Or' as per VB.net
@deanvmc - not sure. The examples on the page linked to indicate that it should

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.