Question

J'ai écrit une classe avec une seule méthode statique qui copie les valeurs de propriété d'un objet à un autre. Peu importe le type de chaque objet, il a seulement des propriétés identiques. Il fait ce dont j'ai besoin, alors je ne le fais pas plus loin, mais quelles améliorations apporteriez-vous?

Voici le code:

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);
        }
    }
}

Je l'utilise comme suit:

EmployeeDTO dto = GetEmployeeDTO();
Employee employee = new Employee();
ShallowCopy.Copy(dto, employee);
Était-ce utile?

La solution

Vos DTO sont-ils sérialisables? Je pense que oui, dans quel cas:

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

Mais notez que je ne suis pas vraiment d'accord avec cette approche générale. Je préférerais un contrat fort pour la copie sur vos DTO que chaque DTO implémente.

Autres conseils

  • Modifiez les noms de paramètre de type pour qu'ils soient conformes aux conventions de dénomination, par exemple. TFrom et TTo, ou TSource et TDest (ou TDestination).

  • Faites la plupart de votre travail dans un type générique plutôt que dans une méthode générique. Cela vous permet de mettre en cache les propriétés, ainsi que l'inférence de type. L'inférence de type est importante sur le champ "TFrom". paramètre, car il autorisera l'utilisation de types anonymes.

  • Vous pourriez potentiellement accélérer le processus en générant du code de manière dynamique pour copier la propriété et la conserver dans un délégué valide pour l'option "from" de " type. Ou potentiellement le générer pour chaque paire de / vers, ce qui signifierait que la copie réelle n'aurait pas besoin d'utiliser la réflexion! (La préparation du code serait un coup unique par paire de types, mais espérons que vous n'en auriez pas trop.)

Une nouvelle méthode qui a créé une nouvelle instance de To et appelée la méthode Copy () avant de renvoyer peut être utile.

Comme ceci:

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

Décidez ce que vous voulez faire si des objets de types partageant certaines propriétés mais pas toutes sont transmis. Vérifiez l'existence de la propriété dans l'objet De dans l'objet À avant d'essayer de définir sa valeur. Faites la "bonne chose" quand vous arrivez à une propriété qui n'existe pas. Si toutes les propriétés publiques doivent être identiques, vous devrez alors vérifier si vous les avez toutes définies sur l'objet To et gérer le cas où vous ne l'êtes pas correctement.

Je suggérerais également que vous souhaitiez utiliser des attributs pour décorer les propriétés à copier et ignorer les autres. Cela vous permettrait de naviguer plus facilement entre les deux objets et de conserver certaines propriétés publiques dérivées plutôt que stockées sur votre objet métier.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top