Wednesday, April 30, 2014

How to make a Private Method in to a Public Method in .NET

Disclaimer: I actually recommend that you try to use this technique as little as possible.

Once and a while we all have to work with a poorly designed API, and sometimes you just really need to access to a private method inside of their code. So when you are out of other options, what can you do to access a private method?

You can try to decompile the code and fork it or extend it, but that might not work due to type constraints, and even if it does then you have to maintain multiple versions. The most common thing to do is use reflection to access the private methods or members, but then you have to share that ugly reflection code everywhere.

Just make an extension method.

Use reflection, but expose it as a extension method. This gives the illusion that the method you are exposing is natively public. This solution is simple and reusable, but please do not abuse it!

public class Demo
{
    private string Hello()
    {
        return "World";
    }
}
 
public static class DemoExtensions
{
    private static readonly MethodInfo HelloMethodInfo = typeof (Demo)
        .GetMethod("Hello", BindingFlags.Instance | BindingFlags.NonPublic);
 
    public static string Hello(this Demo demo)
    {
        return (string) HelloMethodInfo.Invoke(demo, new object[0]);
    }
}
 
public class DemoTests
{
    [Fact]
    public void HelloTest()
    {
        var demo = new Demo();
        var hello = demo.Hello();
        Assert.Equal("World", hello);
    }
}

Enjoy,
Tom

3 comments:

  1. I think your disclaimer warning should use more forceful wording. Something like "Don't ever do this unless forced to do it at gunpoint" It just raises far too many red flags.

    ReplyDelete
    Replies
    1. That's why the disclaimer is the first line of the article, and it's in italics!

      Delete
    2. Just giving you a hard time. :)

      Delete

Real Time Web Analytics