28 Jan
2010

Calling Non-Public Methods

Category:UncategorizedTag: , :

A typical way for invoking a non-public method of a class is by using reflection. This can come in handy in a number of cases. One typical scenario that comes to mind is when the designers of the .NET Framework or another 3rd party framework decided to bury a class or a method as internal while this could perfectly solve a problem (I just hate it when they do that).

Invoking private methods is not considered a best practice in general, but there are cases where you have no other option than to fall back on using reflection. The following code snippet shows how one would typically accomplish that.

public class Subject
{
    private String DoSomething(String input)
    {
        return input;
    }
}

// Calling code
var subject = new Subject();
var doSomething = typeof(Subject).GetMethod("DoSomething", 
    BindingFlags.Instance | BindingFlags.NonPublic);
var result = doSomething.Invoke(subject, new[] { "Hello Muppets" });
Console.WriteLine(result);  

 

We all recognize this piece of code as we’ve done this at some point in one of our coding sessions. What I want to share here is a slightly nicer way to accomplish the same without all the usual reflection ugliness.

// Calling code that uses delegates
var subject = new Subject();
var doSomething = (Func<String, String>)
    Delegate.CreateDelegate(typeof(Func<String, String>), subject, "DoSomething");
Console.WriteLine(doSomething("Hello Freggles"));

 

This code just creates a delegate that matches the signature of the non-public method that we want to call. To me, this approach looks far more elegant. Note that this only works for instance methods and not for static methods.

I hope that this can be of some use.

13 thoughts on “Calling Non-Public Methods

  1. Interesting, but without the method name and only relying on the signature you better have some good tests around it incase an update will add a newmethod with the same signature 🙂

  2. Great tip and the second way is cleaner but I actually prefer the first way. The fact that the original code is so ugly is an indicator to anyone reading it that you’re playing a bit with the dark side of the force. Dangerous code should look dangerous; It doesn’t help to make Darth Vader look like an Ewok.

  3. Here is it’s evil sister:

    static class Reflector
    {
    public static T GetMethod(this object target, string methodName)
    {
    var method = Delegate.CreateDelegate(typeof(T), target, methodName);
    return (T)(object)method;
    }
    }

    Console.WriteLine(subject.GetMethod<Func>(“DoSomething”)(“hello Freggles”));

  4. Pingback: Coding4all

Comments are closed.