2012-03-20 6 views
9

Есть ли способ установить единственное значение в свойстве массива через отражение в C#?Значение параметра в массиве с помощью отражения

Моя собственность определяется следующим образом:

double[] Thresholds  { get; set; } 

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

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

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

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

ответ

15

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

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

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

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

if (value is Array) 
{ 
    Array arr = (Array)value; 
    arr.SetValue(myValue, myIndex); 
} 
else 
{ 
    ... 
} 
+1

«Изменение стоимости имущества» является сбивающим с толку фразой, поскольку это является синонимом «установки свойства» (прямо или косвенно). На самом деле значение свойства здесь ** никогда не изменяется ** (это та же ссылка); это изменение содержимого массива. Кроме того, 'GetValue' нуждается во втором параметре. –

+0

Теперь GetValue исправлено – bluish

0

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

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

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)); 
    } 
Смежные вопросы