Recently, I had to look for a solution to be able to recover a value from a private property.
This value was needed to decode an HTTP stream and unfortunately it was encapsulated (and hidden) by the .NET framework.
Fortunately, in .NET, it is very easy to access a private member of another class.
Of course, this type of mechanism breaks the encapsulation and is contrary to the object principles. Nevertheless, sometimes it becomes necessary.
My need was: I wanted to make a call to a private method in another class. By default, the compiler forbids it, this is the reason for the private keyword.
By the reflection mechanisms proposed by .NET, it is possible to reach almost any member of any class.
The operation is performed as follows:
- First of all, you have to recover the instance of the class you want to “spy on”.
- Then, we get its type with the GetType() method.
- From there, we get either a member directly (if we know the name), or by listing members (GetFields, GetMethods). In the example, I know the name.
- An invocation is then performed to retrieve the value of the member (property or method).
Here’s an example that just shows how it works:
1 2 3 4 | using System; using System.Reflection; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | class MyPrivateClass { private int GetPrivateValue() { return 5; } public int GetPublicValue() { return 10; } } static class Program { /// /// Entry point of our example /// [MTAThread] static void Main() { MyPrivateClass myClass = new MyPrivateClass(); int value1 = myClass.GetPublicValue(); // This is impossible in normal times // value = myClass.GetPrivateValue (); // Recover the type: Type classType = myClass.GetType(); // Retrieve method information // (flags: important for private members) MethodInfo mi = classType.GetMethod("GetPrivateValue", BindingFlags.Instance | BindingFlags.NonPublic); // Make an invocation: object result = mi.Invoke(myClass, null); int value2 = (int)result; Console.Write("value1={0}, value2={1}", value1, value2); Console.ReadLine(); } } |
So that’s a simple way to access a private member. Be careful, however, to use this with caution because all private members can change from one version of the framework to another (which may therefore require you to review the “trick” with each new version).
For those who have already used reflection, have you ever used this type of trick to access hidden values in the .NET framework?