Fun with reflection: Invoking a private method

I was recently working on a project where the use of reflection became one of the proposed solutions.  Before I go any further, allow me to preface this by saying that reflection can be costly and have negative performance impacts.  It is not always type safe and may lead to run-time exceptions.  Other alternatives should be considered before committing to using reflection as a solution. 

The scenario we had was we needed to access a private method inside a legacy .NET assembly.  I'm not going to get into the reasons why.  The alternative was to duplicate all of the logic that was needed from legacy code.  I mentioned to a co-worker that we could use reflection to invoke a private method.  He was skeptical so I provided him with the following spike solution code showing how to do just that. It's a simple, but complete working example that I thought I would share with all of you.

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Reflection;
  4.  
  5. namespace ConsoleApplication1 {
  6.     class Program {
  7.         static void Main(string[] args) {
  8.             HelloWorld hw = new HelloWorld();
  9.  
  10.             hw.SayWhatsUp();
  11.             hw.name = "World";
  12.  
  13.             BindingFlags eFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
  14.             MethodInfo hi = null;
  15.             
  16.             hi = hw.GetType().GetMethod("SayHi", eFlags);
  17.  
  18.             object[] a = new List<object>().ToArray();
  19.             if (hi != null) {
  20.                 hi.Invoke(hw, a);
  21.             } else {
  22.                 Console.WriteLine("Method Not Found.");
  23.             }
  24.  
  25.             Console.ReadLine();
  26.         }
  27.     }
  28.  
  29.  
  30.     public class HelloWorld {
  31.         public string name { get; set; }
  32.  
  33.         public void SayWhatsUp() {
  34.             Console.WriteLine("Whats Up");
  35.         }
  36.  
  37.         private void SayHi() {
  38.             Console.WriteLine("Hi " + name);
  39.         }
  40.     }
  41. }

0 comments:

Post a Comment