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. To access a private
member 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 members will be searched. In this case, only instance members (not 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 file contains the extensions methods of this article and more to access private
members of a class.