Question

As disgussed in .NET Reflection set private property one can set a property with a private setter. But when the property is defined in a base class, System.ArgumentException is thrown : "Property set method not found".

An example can be:

using System;
class Test
{
    public DateTime ModifiedOn { get; private set;}
}

class Derived : Test
{
}

static class Program
{
    static void Main()
    {
        Derived p = new Derived ();
        typeof(Derived).GetProperty("ModifiedOn").SetValue(
            p, DateTime.Today, null);
        Console.WriteLine(p.ModifiedOn);
    }
}

Does anyone know a way to tackle this situation?

Edit: The example given is a simple illustration of the problem. In the real world scenario, I do not know if the property is defined in a base class, or defined in the base of the base class.

Was it helpful?

Solution

I had a similar problem where my private property was declared in a base class. I used DeclaringType to get a handle on the class where the property is defined.

using System;
class Test
{
    public DateTime ModifiedOn { get; private set;}
}

class Derived : Test
{
}

static class Program
{
    static void Main()
    {
        Derived p = new Derived ();

        PropertyInfo property = p.GetType().GetProperty("ModifiedOn");
        PropertyInfo goodProperty = property.DeclaringType.GetProperty("ModifiedOn");

        goodProperty.SetValue(p, DateTime.Today, null);

        Console.WriteLine(p.ModifiedOn);
    }
}

OTHER TIPS

I think this will work:

using System;
class Test
{
    public DateTime ModifiedOn { get; private set;}
}

class Derived : Test
{
}

static class Program
{
    static void Main()
    {
        Derived p = new Derived ();
        typeof(Test).GetProperty("ModifiedOn").SetValue(
            p, DateTime.Today, null);
        Console.WriteLine(p.ModifiedOn);
    }
}

You need to get the property definition from the class its actually defined on not the derived class

EDIT:

To pick it on any base class you will need to look for it on all of the parent classes.

something like this then recurse to the base class till you hit object or find your property

typeof(Derived ).GetProperties().Contains(p=>p.Name == "whatever")

Another option than @LukeMcGregor's one is to use BaseType

typeof(Derived)
    .BaseType.GetProperty("ModifiedOn")
    .SetValue(p, DateTime.Today, null);

I made this reusable method. It handles my scenarios.

    private static void SetPropertyValue(object parent, string propertyName, object value)
    {
        var inherType = parent.GetType();
        while (inherType != null)
        {
            PropertyInfo propToSet = inherType.GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance);
            if (propToSet != null && propToSet.CanWrite)
            {
                propToSet.SetValue(parent, value, null);
                break;
            }

            inherType = inherType.BaseType;
        }
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top