0

I used this SO Question to retrieve a property of an object using reflection. The property I retrieved is another object that has a property called Value that I need to access. All of the potential objects that I retrieve using reflection derive from the same class EntityField and therefore all have a Value property. I saw this SO question that hinted at how I might be able to access the Value property, but I couldn't quite put together the correct code. How can I access the Value property on an object retrieved by reflection?

My Attempts

var parent = entity.GetType().GetProperty("Property");
parent.GetType().GetProperty("Value").SetValue(parent, newValue);  // parent.GetType() is null
(parent as EntityField<T>).Value = newValue;  // Not sure how to dynamically set T since it could be any system type

Main (Original Code)

private static void SetValues(JObject obj, EntityBase entity)
{
    // entity.GetType().GetProperty("Property") returns an EntityField Object
    // I need to set EntityField.Value = obj["Value"] 
    // Current code sets EntityField = obj["Value"] which throws an error
    entity.GetType().GetProperty("Property").SetValue(entity, obj["Value"], null);
}

EntityField

public class EntityField<T> : EntityFieldBase
{
    private Field _Field;
    private T _Value;

    public EntityField(Field field, T value){
        this._Field = field;
        this._Value = value;
    }

    public Field Field
    {
        get
        {
            return this._Field;
        }
        set
        {
            if (this._Field != value)
            {
                this._Field = value;
            }
        }
    }

    public T Value
    {
        get
        {
            return this._Value;
        }
        set
        {
            if (!EqualityComparer<T>.Default.Equals(this._Value, value))
            {
                this._Value = value;
                this._IsDirty = true;
            }
        }
    }
}
Tim Hutchison
  • 3,483
  • 9
  • 40
  • 76

2 Answers2

0

Try this:

entity.GetType().GetProperty("Value").SetValue(entity, obj["Value"], null);

You need to specify the name of the property in the GetProperty() method. I suspect there was no such property called 'Property' :)

Edit: After reading your comments try

entity.Property.GetType().GetProperty("Value").SetValue(entity, obj["Value"], null);
Ross Miller
  • 656
  • 3
  • 9
  • There is a property called `Property`, but that property is an object, not a system type (e.g. String, int). I need to access a property from the object that is the property on the object passed in to SetValue. – Tim Hutchison May 21 '18 at 15:01
  • 1
    I see. In that case then you just need to retrieve that object and run the same code on that object :) It's the same code you just have to run it on the object that Property returns. – Ross Miller May 21 '18 at 15:04
0

Tried the following in LinqPad and it worked...

class TestChild<T>
{
    public T ChildProperty { get; set; }
}

class TestParent<T>
{ 
    public TestChild<T> ParentProperty { get; set; }    
}

void Main()
{
    var instance = new TestParent<string>
    {
        ParentProperty = new TestChild<string>()
    };

    instance.GetType()
            .GetProperty("ParentProperty")
            .GetValue(instance)
            .GetType()
            .GetProperty("ChildProperty")
            .SetValue(instance.ParentProperty, "Value");

    Console.WriteLine(instance.ParentProperty.ChildProperty);
}
Stevo
  • 1,424
  • 11
  • 20
  • I think this is really close...unfortunately, `Test` is really a generic `Test` so I would need to somehow pass a dynamic type to a generic object – Tim Hutchison May 21 '18 at 15:36
  • Ah, sorry - didn't notice the generic aspect of the question. Have modified the answer. – Stevo May 21 '18 at 15:41
  • I'm investigating how to do this if I don't know the type at runtime. For example, Test could have T = String, T= int, T=Guid, etc. Any thoughts? – Tim Hutchison May 21 '18 at 15:46
  • Just modified answer again to account for that... :) – Stevo May 21 '18 at 15:48
  • Thanks for the help :) What would you do though if you have `Test` with a child property of `TestField`? I can get to `TestField` on `Test`, but I need to get to `Test.TestField.Value` – Tim Hutchison May 21 '18 at 15:54
  • Further modified answer... :) – Stevo May 21 '18 at 16:25