Pregunta

He escrito una clase con un único método estático que copia los valores de propiedad de un objeto a otro. No le importa de qué tipo es 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?

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 de la siguiente manera:

EmployeeDTO dto = GetEmployeeDTO();
Employee employee = new Employee();
ShallowCopy.Copy(dto, employee);
¿Fue útil?

Solución

¿Sus DTO son serializables? Lo esperaría, 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 sólido para copiar en sus DTO que cada DTO implemente.

Otros consejos

  • 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).

  • Realiza la mayor parte de tu trabajo en un tipo genérico en lugar de solo un método genérico. Eso le permite almacenar en caché las propiedades, además de permitir la inferencia de tipos. La inferencia de tipos es importante en el " TFrom " parámetro, ya que permitirá el uso de tipos anónimos.

  • Potencialmente, podría hacerlo cegadoramente rápido generando dinámicamente código para copiar la propiedad y mantenerlo en un delegado que sea válido para el " desde " tipo. ¡O potencialmente lo genere para cada par de / a, lo que significaría que la copia real no necesitaría usar reflexión en absoluto! (La preparación del código sería un éxito único por par de tipos, pero con suerte no tendría demasiados pares).

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

Me gusta esto:

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

Decide qué quieres hacer si pasas objetos de tipos que comparten algunas propiedades pero no todas. Verifique la existencia de la propiedad en el objeto From en el objeto To antes de intentar establecer su valor. Haz lo "correcto" cuando vienes 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 en el que no lo ha hecho de manera adecuada.

También te sugiero que quieras usar atributos para decorar las propiedades que necesitan ser copiadas 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 que se derivan en lugar de almacenarse en su objeto comercial.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top