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 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. metroidsnes
    January 29th, 2019 at 05:35 | #1

    Thanks for posting these methods, they’re very useful for debugging.

  2. October 1st, 2020 at 16:23 | #2

    Very nice. Although you should replace ArgumentOutOfRangeException with InvalidOperationException to correct the semantic meaning of the exception.

  3. October 1st, 2020 at 16:32 | #3

    In my last comment, prefer MissingMemberException to InvalidOperationException. It’s even more accurate.

  1. No trackbacks yet.