Home > C#, Reflection > C#: How to set or get value of a private or internal property through the Reflection

C#: How to set or get value of a private or internal property through the Reflection

December 17th, 2012 Admin Leave a comment Go to comments

    Quite often in my practice I need to interact with hidden (internal and private) properties of an object. It easily can be done through the Reflection API. The only complication may arise here it’s when a private property is defined in one of the base classes. In this case we have to iterate through the object’s class hierarchy, looking for the property. So, trying to simplify getting and setting values of object’s private and internal properties, I’ve implemented a couple of the methods-extensions listed below. The GetPropertyValue method returns value of a private or internal property, and the SetPropertyValue, in turn, sets value to a private or internal property.

public static class ReflectionHelper
{
 private static PropertyInfo GetPropertyInfo(Type type, string propertyName)
 {
   PropertyInfo propInfo = null;
   do
   {
     propInfo = type.GetProperty(propertyName,
            BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
     type = type.BaseType;
   }
   while (propInfo == null && type != null);
   return propInfo;
 }

 public static object GetPropertyValue(this object obj, string propertyName)
 {
   if (obj == null)
     throw new ArgumentNullException("obj");
   Type objType = obj.GetType();
   PropertyInfo propInfo = GetPropertyInfo(objType, propertyName);
   if (propInfo == null)
     throw new ArgumentOutOfRangeException("propertyName",
       string.Format("Couldn't find property {0} in type {1}", propertyName, objType.FullName));
   return propInfo.GetValue(obj, null);
 }

 public static void SetPropertyValue(this object obj, string propertyName, object val)
 {
    if (obj == null)
      throw new ArgumentNullException("obj");
    Type objType = obj.GetType();
    PropertyInfo propInfo = GetPropertyInfo(objType, propertyName);
    if (propInfo == null)
      throw new ArgumentOutOfRangeException("propertyName",
        string.Format("Couldn't find property {0} in type {1}", propertyName, objType.FullName));
    propInfo.SetValue(obj, val, null);
 }
}

Below is how to use the methods. Let’s assume we have the following hierarchy of classes:

class SomeBase
{
    private bool IsLimited { get; set; }

    public SomeBase()
    {
        IsLimited = false;
    }
}

class SomeClass : SomeBase
{
    private  string Str { get; set; }
    internal int    Int { get; set; }

    public SomeClass()
    {
        Str = "initial value";
        Int = 0;
    }
}

So, we need to get and set hidden properties’ values from within a project (library) different to the one where the SomeBase and SomeClass are located. A possible code may look like the following:

SomeClass someObj = new SomeClass();

// the Str and Int properties will be found on the first step of iteration,
// so, the base class won't be analyzed
string currentStrValue = (string)someObj.GetPropertyValue("Str");
int    currentIntValue = (int)someObj.GetPropertyValue("Int");

// the IsLimited propertiy will be found on the second step of iteration,
// so, the base class will be analyzed as well
bool currentBoolValue = (bool)someObj.GetPropertyValue("IsLimited");

// the Str and Int properties will be found on the first step of iteration,
// so, the base class won't be analyzed
someObj.SetPropertyValue("Str", "brand new value");
someObj.SetPropertyValue("Int", -1);

// the IsLimited propertiy will be found on the second step of iteration,
// so, the base class will be analyzed as well
someObj.SetPropertyValue("IsLimited", true);
Related posts:
 
Categories: C#, Reflection Tags: ,
  1. Josh
    June 14th, 2013 at 21:52 | #1

    This is a great tool. I was searching for how to set private properties through reflection and found your site. The functionality encompasses the tools I had already written (for public properties) and what I needed for private properties. For my use, I also added BindingFlags.Static to the list as that is often used in my application. Thanks for the post!

  1. No trackbacks yet.