如何使用反射修改集合中的特定项
本文关键字:集合 何使用 反射 修改 | 更新日期: 2023-09-27 18:32:34
我在集合中有一个项目,我需要使用反射进行修改 - 我正在使用反射,因为直到运行时我才知道泛型集合的确切类型。
我知道如何使用 SetValue()方法来设置通过集合检索的属性的值,但是我可以使用 SetValue() 在集合中设置实际对象吗?
IEnumerable businessObjectCollection = businessObject as IEnumerable;
foreach (Object o in businessObjectCollection)
{
// I want to set the "o" here to some replacement object in the collection if
// a property on the object equals something
Type t = o.GetType();
PropertyInfo identifierProperty = o.GetType().GetProperty("Identifier");
long entityID = (long)identifierProperty.GetValue(o, null);
if (replacementEntity.Identifier == entityID)
{
// IN THIS CASE: set "o" to be the replacementEntity object
// defined somewhere else.
// I can retrieve the object itself using this code, but
// would I set the object with SetValue?
object item = businessObjectCollection.GetType().GetMethod("get_Item").Invoke(businessObjectCollection, new object[] { 1 });
}
}
collection.GetType().GetProperty("Item").SetValue(collection, o, new object[] { 1 })
与其
尝试修改可枚举项,不如将其替换为执行内联替换的新枚举项。这真的取决于你之后用它做什么,虽然 YMMV。
IEnumerable newCollection = businessObjectCollection.Cast<object>().Select((o) =>
{
Type t = o.GetType();
PropertyInfo identifierProperty = o.GetType().GetProperty("Identifier");
long entityID = (long)identifierProperty.GetValue(o, null);
if (replacementEntity.Identifier == entityID)
{
return replacementEntity;
}
return o;
});
好吧,你用get_Item
来检索它,所以你应该能够调用set_Item
来设置它:
businessObjectCollection.GetType().GetMethod("set_Item").Invoke(businessObjectCollection, new object[] { 1, replacementEntity });
请注意,如果集合不是支持索引访问的类型,则会爆炸。
此方法将对象添加到对象上所述对象的集合属性中。
obj 是包含属性集合的父对象
属性名称是集合属性的名称
值是要添加到集合的对象
private object AddItemToCollectionProperty( Object obj, string propertyName, Object value )
{
PropertyInfo prop = obj.GetType().GetProperty( propertyName );
if( prop != null )
{
try
{
MethodInfo addMethod = prop.PropertyType.GetMethod( "Add" );
if(addMethod ==null)
{
return obj;
}
addMethod.Invoke( prop.GetValue(obj), new object [] { value } );
}
catch( Exception ex )
{
Debug.Write( $"Error setting {propertyName} Property Value: {value} Ex: {ex.Message}" );
}
}
else
{
Debug.Write( $"{propertyName} Property not found: {value}" );
}
return obj;
}