【问题标题】:Setting value in an array via reflection通过反射在数组中设置值
【发布时间】:2012-04-04 16:58:02
【问题描述】:

有没有办法通过 c# 中的反射在数组属性中设置单个值?

我的属性是这样定义的:

double[]    Thresholds      { get; set; }

对于“普通”属性,我使用此代码通过反射进行设置:

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

如何更改此代码以将数组属性中的值设置在任意位置? 谢谢!

顺便说一句:我尝试使用 index 参数,但这似乎只适用于索引属性,而不是数组属性...

【问题讨论】:

    标签: c# arrays reflection propertyinfo setvalue


    【解决方案1】:

    您实际上并没有设置属性,只是更改了属性值:

    object value = myObject.GetType().GetProperty(nameOfPropertyToset).GetValue(myObject, null);
    
    if (value is Array)
    {
        Array arr = (Array)value;
        arr.SetValue(myValue, myIndex);
    }
    else
    {
        ...
    }
    

    【讨论】:

    • “更改属性值”的措辞令人困惑,因为它与“设置属性”(直接或间接)同义。其实这里的属性值从不改变(是同一个引用);改变的是数组内容。另外,GetValue 这里需要第二个参数。
    【解决方案2】:

    当你这样做时:

    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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-02-07
        • 2019-04-22
        • 1970-01-01
        • 2014-10-07
        • 1970-01-01
        • 1970-01-01
        • 2019-04-19
        • 1970-01-01
        相关资源
        最近更新 更多