I have two objects from this class:
public class A
{
public int Id { get; set; }
public string Name { get; set; }
public IList<B> Bs { get; set; }
}
public class B
{
public string Description { get; set; }
public IList<C> Cs { get; set; }
}
public class C
{
public string Description { get; set; }
}
Now I want to loop through all the properties of the two object instances with FastMember and copy the properties from object 1
to object 2
.
Here's what I got so far (not working!)
// Set accessors
var sourceAccessor = ObjectAccessor.Create(object1);
var targetAccessor = ObjectAccessor.Create(object2);
foreach (var sourceItem in (IList)sourceAccessor.Target)
{
var targetItemAccessor = ObjectAccessor.Create(targetAccessor.Target);
var sourceItemAccessor = ObjectAccessor.Create(sourceItem);
// Overwrite property
targetItemAccessor[p] = sourceItemAccessor[p];
}
this code is obviously not working...any ideas? Thanks!
You can create a shallow copy with the help of the TypeAccessor
using something like:
var sourceAccessor = ObjectAccessor.Create(object1);
var targetAccessor = ObjectAccessor.Create(object2);
var access = TypeAccessor.Create(typeof(A));
var members = access.GetMembers();
foreach (var member in members)
{
targetAccessor[member.Name] = sourceAccessor[member.Name];
}
Have a look at the FastMember tests for usage examples.
For a deep copy, you could check either the property name or use the property type to determine whether to apply a deep copy of lists or if a shallow copy is sufficient.
Edit: Here is an example for a simplified version that recursively copies properties of type IList
(see this question on how to determine which property is a list), assuming the source and target object's lists have the same length:
private static void MirrorObject(object object1, object object2)
{
var sourceAccessor = ObjectAccessor.Create(object1);
var targetAccessor = ObjectAccessor.Create(object2);
var access = TypeAccessor.Create(object1.GetType());
var members = access.GetMembers();
foreach (var member in members)
{
if (member.Type.IsGenericType && (member.Type.GetGenericTypeDefinition() == typeof(IList<>)))
{
var list1 = (IList)sourceAccessor[member.Name];
var list2 = (IList)targetAccessor[member.Name];
if (list1.Count != list2.Count)
{
throw new ArgumentException("Lists need to be of the same length.");
}
for (var i = 0; i < list1.Count; ++i)
{
MirrorObject(list1[i], list2[i]);
}
}
else
{
targetAccessor[member.Name] = sourceAccessor[member.Name];
}
}
}