Setting value in an array via reflection
Asked Answered
B

3

14

Is there a way to set a single value in an array property via reflection in c#?

My property is defined like this:

double[]    Thresholds      { get; set; }

For "normal" properties I use this code to set it via reflection:

PropertyInfo pi = myObject.GetType().GetProperty(nameOfPropertyToSet);
pi.SetValue(myObject, Convert.ChangeType(valueToSet, pi.PropertyType), null);

How would I have to change this code to set the value in an array property at an arbitrary position? Thanks!

BTW: I tried to use the index parameter, but that seems only to work for indexed properties, not properties that are arrays...

Butcherbird answered 20/3, 2012 at 8:0 Comment(0)
C
22

When you do:

obj.Thresholds[i] = value;

that is semantically equivalent to:

double[] tmp = obj.Thresholds;
tmp[i] = value;

which means you don't want a SetValue at all; rather, you want to use GetValue to obtain the array, and then mutate the array. If the type is known to be double[], then:

double[] arr = (double[]) pi.GetValue(myObject, null);
arr[i] = value;

otherwise perhaps the non-generic IList approach (since arrays implement IList):

IList arr = (IList) pi.GetValue(myObject, null);
arr[i] = value;

If it is a multi-dimensional array, you'll have to use Array in place of IList.

Cheatham answered 20/3, 2012 at 8:6 Comment(0)
L
9

You are not actually setting the property, just changing the property value:

object value = myObject.GetType().GetProperty(nameOfPropertyToset).GetValue(myObject, null);

if (value is Array)
{
    Array arr = (Array)value;
    arr.SetValue(myValue, myIndex);
}
else
{
    ...
}
Liberalize answered 20/3, 2012 at 8:5 Comment(1)
"changing the property value" is confusing phrasing, as that is synonymous with "setting the property" (directly or indirectly). Actually, the property value here never changes (it is the same reference); it is the array contents that change. Also, GetValue needs a 2nd parameter here.Cheatham
E
0

Te code here will work for on it, its design to fill a 10 position array, you can do it for any size array.

The function PopulateInstance populate a data structure with what I need.

    object singleval;
    Array arrayval;
    System.Type LocalPType = obj.GetType().GetField(node.Name).FieldType;
    if (LocalPType.IsArray)
    {
        singleval = TreeNodeProperty.CreateNewInstance(LocalPType.GetElementType());
        arrayval =  Array.CreateInstance(LocalPType, 10);
        for(int i = 0; i < 10; i++)
        {
            singleval = PopulateInstance(singleval, node);
            arrayval.SetValue(singleval, i);
        }
        obj.GetType().GetField(node.Name).SetValue(obj, arrayval);
    }
    else
    {
        object val;
        val = Activator.CreateInstance(LocalPType);
        obj.GetType().GetField(node.Name).SetValue(obj,         PopulateInstance(val, node));
    }
Entomostracan answered 16/11, 2016 at 0:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.