2012-03-20 33 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'在这里需要第二个参数。 – 2012-03-20 08:09:53

+0

现在修正了GetValue – bluish 2014-02-07 16:10:14

0

这里的代码将适用于它,它的设计,以填补一个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)); 
    }