Accessing private members

Accessing private members of a .NET class is normally not a good idea, a thing you shouldn’t do. But in some cases it is the best opportunity you have. If you maintain code which wraps some legacy code where the source code is missing. Or when classes are binary serialized and you have to migrate them because the class changed. Accessing private members in .NET isn’t very difficult. A private field or property can be read with the code below. It is implemented as generic extension methods.

public static T GetPrivateField<T>(this object obj, string name)
{
    BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic;
    Type type = obj.GetType();
    FieldInfo field = type.GetField(name, flags);
    return (T)field.GetValue(obj);
}

public static T GetPrivateProperty<T>(this object obj, string name)
{
    BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic;
    Type type = obj.GetType();
    PropertyInfo field = type.GetProperty(name, flags);
    return (T)field.GetValue(obj, null);
}

With the Type of the object you can get a Fieldinfo or the PropertyInfo object for a specified field or property. The BindingFlags define in which scope the members will be searched. In this case only instance members (no static) which are private will be found. If you are trying to access public members you will get an error. The value can be read by calling the GetValue method on the info objects. Writing values or even calling private methods is similar.

public static void SetPrivateField(this object obj, string name, object value)
{
    BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic;
    Type type = obj.GetType();
    FieldInfo field = type.GetField(name, flags);
    field.SetValue(obj, value);
}

public static void SetPrivateProperty(this object obj, string name, object value)
{
    BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic;
    Type type = obj.GetType();
    PropertyInfo field = type.GetProperty(name, flags);
    field.SetValue(obj, value, null);
}

public static T CallPrivateMethod<T>(this object obj, string name, params object[] param)
{
    BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic;
    Type type = obj.GetType();
    MethodInfo method = type.GetMethod(name, flags);
    return (T)method.Invoke(obj, param);
}

You also work with the info object, but you call the method SetValue. If your parameter object has the wrong type an error occurs. When you want to call a private method, you must use the Invoke method in the MethodInfo class. This method takes all parameters as input which the private method takes. The download below contains the extensions methods of this article and more to access private members of a class.

Private Extensions Class (5.06 kb)

28 thoughts on “Accessing private members

  1. Fluent NH has something like that for private fields, since NH can map to private fields and those members aren’t accessible through the usual expression-based syntax. Only, they called it "Reveal" ;)

  2. Admiring the time and effort you put into your weblog and detailed data you provide! I will bookmark your weblog and have my kids test up right here often. Thumbs up!

Comments are closed.