Calling Non-Public Methods

January 28th, 2010

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.

Jan Van Ryswyck

  • http://ElegantCode.com Mark Nijhof

    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 :)

  • http://elegantcode.com/ Jan Van Ryswyck

    One should always have good tests :-)

  • http://CodeRenaissance.com Dave H.

    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.

  • http://www.timvw.be Tim Van Wassenhove

    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”));

  • http://loltroll.co.uk/methods-to-quit-smoking/methods-to-quit-smoking-cigarettes-wmv/ Methods To Quit Smoking Cigarettes.wmv |

    [...] Elegant Code » Calling Non-Public Methods [...]

  • http://loltroll.co.uk/methods-to-quit-smoking/latest-methods-to-quit-smoking-auctions/ Latest Methods To Quit Smoking Auctions |

    [...] Elegant Code » Calling Non-Public Methods [...]

  • http://loltroll.co.uk/quit-smoking-methods/quit-smoking-methods/ Quit Smoking Methods |

    [...] Elegant Code » Calling Non-Public Methods [...]

  • http://loltroll.co.uk/quit-smoking-tip/look-at-the-effective-stop-smoking-methods-in-this-nlp-video/ Look At The Effective Stop Smoking Methods In This NLP Video |

    [...] Elegant Code » Calling Non-Public Methods [...]

  • http://www.kozlenko.info/2010/02/02/daily-links-2010-02-01/ Daily links 2010-02-01 | Maxim’s blog

    [...] Elegant Code: Calling Non-Public Methods Got a library class where method is private, or you need to access this in your unit test? Use .NET reflection [...]

  • http://blogs.msdn.com/ddietric/ Dennis “D.C.” Dietrich

    Interesting. I’ve written an experimental runtime wrapper generator that uses that technique internally to improve performance (requires C# 4.0 though):
    http://blogs.msdn.com/ddietric/archive/2010/01/24/d-c-and-the-wrapper-factory.aspx

  • http://www.coding4all.com/2010/04/answer-by-ruben-bartelink-for-hidden-features-of-c/ Coding4all

    [...] trick for calling private methods using Delegate.CreateDelegate is extremely [...]

  • http://elegantcode.com/2010/04/16/linfu-duck-typing-part-1-revealing-secrets/ Elegant Code » Linfu Duck Typing Part 1 – Revealing Secrets

    [...] order to access and use this private class. An even better and more efficient approach would be to use delegates instead. But there’s also another simple and elegant solution which I briefly mentioned in a [...]

  • http://twitter.com/_manuc66_ manuc66

    Interesting, but have you an idea about which one is faster ? And othant advantage other than not using reflection ?

blog comments powered by Disqus