Property set method not found in a derived type
Asked Answered
R

4

17

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.

Replete answered 6/4, 2012 at 9:15 Comment(0)
P
21

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);
    }
}
Porfirioporgy answered 19/9, 2013 at 15:6 Comment(0)
G
10

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")
Gascon answered 6/4, 2012 at 9:18 Comment(1)
This would definitely work, if the base type was known. Please see my edit.Replete
D
8

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

typeof(Derived)
    .BaseType.GetProperty("ModifiedOn")
    .SetValue(p, DateTime.Today, null);
Dubuffet answered 6/4, 2012 at 9:21 Comment(2)
Yes, if the inheritance tree was of length one. Please see my edit.Replete
Then you walk the line... You can stop at System.Object.Phalangeal
T
5

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;
        }
    }
Transit answered 1/8, 2013 at 5:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.