在c#中使用反射设置索引属性的值
本文关键字:索引 属性 设置 反射 | 更新日期: 2023-09-27 17:49:34
我有一个类,它有
ObservableCollection<int>
作为属性,我试图改变该类实例的属性内的值。这是我的代码,这是得到一个TargetException:
object[] index = null;
var originalPropertyName = propertyName;
if (propertyName.Contains("[") && propertyName.Contains("]"))
{
index = new object[1];
index[0] = Convert.ToInt32(propertyName.Split('[')[1].Split(']')[0]);
propertyName = propertyName.Split('[')[0];
}
PropertyInfo pi = item.GetType().GetProperty(propertyName);
PropertyInfo opi = item.GetType().GetProperty(originalPropertyName);
Type pType = index != null ? pi.PropertyType.GetGenericArguments()[0] : pi.PropertyType;
if (pi != null)
{
object convertedValue = Convert.ChangeType(value, pType);
if (index == null)
{
item.GetType().GetProperty(propertyName).SetValue(item, convertedValue, null);
}
else
{
//PropertyInfo ipi = pi.PropertyType.GetProperties().Single(p => p.GetIndexParameters().Length > 0);
//var collection = pi.GetValue(item, index);
//collection.GetType().GetProperty("Value").SetValue(collection, convertedValue, null);
var _pi = pi.PropertyType.GetProperty("Item");
_pi.SetValue(pi, convertedValue, index);
}
}
如何获得propertyName上面没有显示,但是在索引属性的情况下,它以"IndexedProperty[10]"为例开始它的生命。
在"else"之后的评论中,你可以看到我尝试过的其他事情,通过阅读其他stackoverflow帖子和其他论坛上关于如何做到这一点,但到目前为止我已经失败了。什么好主意吗?
将属性强制转换为ObservableCollection是不可行的,因为我希望它是动态的。
整个事情的概念是拥有一个数据绑定的DataGrid,并通过更新每个实例的适当属性来正确地粘贴工作,无论属性是否被索引。非索引属性工作良好,但我不能得到ObservableCollection的工作
以ObservableCollection<int>
为属性的类实际上不具有传统意义上的索引器的索引属性。它只是有一个非索引属性本身有一个索引器。因此,您需要使用GetValue
开始(不指定索引),然后在结果上获取索引器。
基本上,你需要记住:
foo.People[10] = new Person();
等价于:
var people = foo.People; // Getter
people[10] = new Person(); // Indexed setter
看起来你已经接近了,还有注释掉的代码:
//var collection = pi.GetValue(item, index);
//collection.GetType().GetProperty("Value").SetValue(collection, convertedValue, null);
…但是你在错误的点上应用了索引。你想要(我认为——这个问题不是很清楚):
var collection = pi.GetValue(item, null);
collection.GetType()
.GetProperty("Item") // Item is the normal name for an indexer
.SetValue(collection, convertedValue, index);
试试这个,我不确定它是否会工作
_pi.SetValue(pi, convertedValue, new object[] { (int) 0 });
//where 0 is the index in which you want to insert the value, in this case to index 0