Reputation: 753
Edit: Move along please, nothing to see here.
The solution to this question had nothing to do with Reflection and everything to do with me not paying attention to the implementation of the collection property in a base class.
I'm trying to add an item to a collection using Reflection using the following method:
public void AddReferenceToCollection(object targetResource, string propertyName, object resourceToBeAdded)
{
Type targetResourceType = targetResource.GetType();
PropertyInfo collectionPropertyInfo = targetResourceType.GetProperty(propertyName);
// This seems to get a copy of the collection property and not a reference to the actual property
object collectionPropertyObject = collectionPropertyInfo.GetValue(targetResource, null);
Type collectionPropertyType = collectionPropertyObject.GetType();
MethodInfo addMethod = collectionPropertyType.GetMethod("Add");
if (addMethod != null)
{
// The following works correctly (there is now one more item in the collection), but collectionPropertyObject.Count != targetResource.propertyName.Count
collectionPropertyType.InvokeMember("Add", System.Reflection.BindingFlags.InvokeMethod, null, collectionPropertyObject, new[] { resourceToBeAdded });
}
else
{
throw new NotImplementedException(propertyName + " has no 'Add' method");
}
}
However, it appears that the call to targetResource.GetType().GetProperty(propertyName).GetValue(targetResource, null)
returns a copy of targetResource.propertyName
and not a reference to it and so the subsequent call to collectionPropertyType.InvokeMember
affects the copy and not the reference.
How can I add the resourceToBeAdded
object to the propertyName
collection property of the targetResource
object?
Upvotes: 1
Views: 2666
Reputation: 46919
Try this:
public void AddReferenceToCollection(object targetResource, string propertyName, object resourceToBeAdded)
{
var col = targetResource.GetType().GetProperty(propertyName).GetValue(targetResource, null) as IList;
if(col != null)
col.Add(resourceToBeAdded);
else
throw new InvalidOperationException("Not a list");
}
Edit: Test usage
void Main()
{
var t = new Test();
t.Items.Count.Dump(); //Gives 1
AddReferenceToCollection(t, "Items", "testItem");
t.Items.Count.Dump(); //Gives 2
}
public class Test
{
public IList<string> Items { get; set; }
public Test()
{
Items = new List<string>();
Items.Add("ITem");
}
}
Upvotes: 4