Установка значения в массиве с помощью отражения - PullRequest
10 голосов
/ 20 марта 2012

Есть ли способ установить одно значение в свойстве массива через отражение в c #?

Моя собственность определена так:

double[]    Thresholds      { get; set; }

Для "обычных" свойств я использую этот код, чтобы установить его с помощью отражения:

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

Как мне изменить этот код, чтобы установить значение свойства массива в произвольной позиции? Спасибо!

Кстати: я пытался использовать параметр index, но, похоже, он работает только для индексированных свойств, а не для свойств, которые являются массивами ...

Ответы [ 3 ]

16 голосов
/ 20 марта 2012

Когда вы делаете:

obj.Thresholds[i] = value;

, что семантически эквивалентно:

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

, что означает, что вы вообще не хотите SetValue ;скорее, вы хотите использовать GetValue для получения массива, а затем мутировать массив.Если известно, что типом является double[], то:

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

в противном случае возможно неуниверсальный подход IList (поскольку массивы реализуют IList):

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

Если это многомерный массив, вам придется использовать Array вместо IList.

5 голосов
/ 20 марта 2012

Вы фактически не устанавливаете свойство, просто меняете значение свойства:

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

if (value is Array)
{
    Array arr = (Array)value;
    arr.SetValue(myValue, myIndex);
}
else
{
    ...
}
0 голосов
/ 16 ноября 2016

Код здесь будет работать для него, его дизайн для заполнения массива из 10 позиций, вы можете сделать это для массива любого размера.

Функция PopulateInstance заполнить структуру данныхчто мне нужно.

    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));
    }
...