C#reflection:如何设置嵌套列表的嵌套属性

时间:2018-02-09 08:04:29

标签: c# list generics reflection

想象一下"路径" :

MyObject.MyFirstList [0] .MySecondList [0] .MyProperty =" Hello"

MyProperty的类型为String。 在编译时不知道任何类型,只有运行时通过反射汇编。

我拥有一切,但我无法使用SetValue在第一个列表中设置第二个列表。我总是得到null-ref异常或"目标类型不匹配"。

到目前为止我尝试过:

迭代1:

var constructedList = Activator.CreateInstance(constructedListType);
target.GetType().GetProperty(propertyToAdd).SetValue(target, constructedList)

迭代2:

同样的方式,也有效。所以现在我们有MyObject.MyFirstList [0] .MySecondList []

迭代3:TODO:创建MySecondList的第一个对象的实例,并将其MyProperty属性设置为created属性:

var target = Activator.CreateInstance(typeOfItem);
target.GetType().GetProperty(propertyToAdd)?.SetValue(target, null);

总结一下这个问题:

这有效:

someInstance.GetType().GetProperty(someProperty).SetValue(someInstance, objToSet);

为什么这样的事情不起作用?或者它 - 如果是的话,怎么样?

someInstance.GetType().GetProperty(someList.listInsideSomeList.finalProperty).SetValue(...);

1 个答案:

答案 0 :(得分:3)

简而言之,反射为您提供了获取类型信息的方法。它不能用于引用其他类型的属性(如上一个示例所示)。

你走在正确的轨道上,但你需要在你的道路上从右向左走。所以你需要一些嵌套属性。首先创建嵌套对象,例如:

var objNested = Activator.CreateInstance(objNestedType);
objNestedType.GetProperty(nestedPropertyName).SetValue(objNested, value);

然后将新创建的对象添加到其“父”:

var objBase = Activator.CreateInstance(objBaseType);
objBaseType.GetProperty(basePropertyName).SetValue(objBase, objNested);

阵列有点不同。 Reflection希望您在使用propertyinfo.SetValue时记下最终值,如果是数组,则这是整个数组值。为此,您可以使用Array.CreateInstance(typeof(arrayType), arrayLength)创建一个新数组,并使用'SetValue(object,index)'方法设置其内容。