Доступны библиотеки, облегчающие (и ускоряющие) работу с отражением. Например, Fasterflect позволяет написать следующее:
// copy only the specified named properties
source.MapProperties( target, "FirstName", "LastName" );
Из вашего описания звучит так, будто вам нужно что-то рекурсивное. Я написал метод DeepClone для Fasterflect, который, я считаю, послужит хорошей отправной точкой для того, что вам нужно. Чтобы адаптировать код, вам нужно изменить его так, чтобы (а) принимать параметр целевого объекта вместо внутреннего создания экземпляра, (б) получать / задавать свойства вместо полей и (в) принимать список именованных свойств для включения.
public static T DeepClone<T>( this T source ) where T : class, new()
{
return source.DeepClone( null );
}
Обратите внимание на параметр карты в приватном методе. Это позволяет мне отслеживать экземпляры, созданные (или, в вашем случае, посещенные), чтобы мы могли поступать правильно, встречая циклические ссылки.
private static T DeepClone<T>( this T source, Dictionary<object, object> map )
where T : class, new()
{
Type type = source.GetType();
IList<FieldInfo> fields = type.Fields( Flags.StaticInstanceAnyVisibility );
var clone = type.CreateInstance() as T;
map = map ?? new Dictionary<object, object>();
map[ source ] = clone;
object[] values = fields.Select( f => GetValue( f, source, map ) ).ToArray();
for( int i = 0; i < fields.Count; i++ )
{
fields[ i ].Set( clone, values[ i ] );
}
return clone;
}
private static object GetValue( FieldInfo field, object source, Dictionary<object, object> map )
{
object result = field.Get( source );
object clone;
if( map.TryGetValue( result, out clone ) )
{
return clone;
}
bool follow = result != null && result.GetType().IsClass && result.GetType() != typeof(string);
return follow ? result.DeepClone( map ) : result;
}
Обратите внимание, что в коде используются другие методы Fasterflect для ускорения реального отражения, но если вы не хотите зависеть от библиотеки, это легко заменить.
Отказ от ответственности: я участвую в указанном проекте в качестве участника.