2009-01-22 20 views
5

Escribí una clase con un único método estático que copia los valores de propiedad de un objeto a otro. No importa qué tipo sea cada objeto, solo que tienen propiedades idénticas. Hace lo que necesito, así que no lo estoy diseñando más, pero ¿qué mejoras harías?¿Cómo mejorarías esta clase de copia superficial?

Aquí está el código:

public class ShallowCopy 
{ 
    public static void Copy<From, To>(From from, To to) 
     where To : class 
     where From : class 
    { 
     Type toType = to.GetType(); 
     foreach (var propertyInfo in from.GetType().GetProperties(BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance)) 
     { 
      toType.GetProperty(propertyInfo.Name).SetValue(to, propertyInfo.GetValue(from, null), null); 
     } 
    } 
} 

lo estoy usando la siguiente manera:

EmployeeDTO dto = GetEmployeeDTO(); 
Employee employee = new Employee(); 
ShallowCopy.Copy(dto, employee); 
+0

¿Cómo utilizamos esto con una lista o un objeto que tiene varios Lista ¿listas en él? –

+1

Eso sería una copia * profunda *. Básicamente es el mismo que el anterior pero recursivo donde se encuentra un 'PropertyInfo' con un' PropertyType' que es heredable de 'IEnumerable'. Tendrás que lidiar con la limpieza del objetivo enumerable y las cosas, obviamente. –

Respuesta

6

Son sus dtos serializable? Yo esperaría eso, en cuyo caso:

MemberInfo[] sm = FormatterServices.GetSerializableMembers(typeof(From)); 
object[] data = FormatterServices.GetObjectData(from, sm); 
FormatterServices.PopulateObjectMembers(to, sm, data); 

Pero tenga en cuenta que realmente no estoy de acuerdo con este enfoque general. Preferiría un contrato fuerte para copiar en sus DTO que implemente cada DTO.

2

Un nuevo método que crea una nueva instancia de To y llama al método Copy() antes de regresar podría ser útil .

De esta manera:

public static To Create<From, To>(From from) 
    where To : class, new() 
    where From : class 
{ 
    var to = new To(); 
    Copy(from, to); 
    return to; 
} 
1

Decida qué quiere hacer si se pasan objetos de tipos que comparten algunas propiedades pero no todas. Compruebe la existencia de la propiedad en el objeto From en el objeto To antes de intentar establecer su valor. Haga lo "correcto" cuando llegue a una propiedad que no existe. Si todas las propiedades públicas deben ser idénticas, deberá verificar si las ha configurado todas en el objeto To y manejar el caso donde no lo haya hecho de forma adecuada.

También le sugiero que desee utilizar atributos para decorar las propiedades que deben copiarse e ignorar otras. Esto le permitiría ir y venir entre los dos objetos diferentes más fácilmente y continuar manteniendo algunas propiedades públicas derivadas en lugar de almacenadas en su objeto comercial.

4
  • Cambie los nombres de los parámetros de tipo para cumplir con las convenciones de nomenclatura, p. TFrom y TTo, o TSource y TDest (o TDestination).

  • Haga la mayor parte de su trabajo en un tipo genérico en lugar de en un método genérico. Eso le permite almacenar en caché las propiedades, así como también permitir la inferencia de tipo. La inferencia de tipo es importante en el parámetro "TFrom", ya que permitirá el uso de tipos anónimos.

  • Puede hacer que sea deslumbrantemente rápido generando código dinámicamente para copiar la propiedad y mantenerla en un delegado que es válido para el tipo "de". O potencialmente generarlo para cada par de/a, lo que significaría que la copia real no necesitaría usar ningún tipo de reflejo. (Preparando el código sería una sola vez golpeado por par de tipos, pero espero que no tendría demasiados pares.)

Cuestiones relacionadas