Voici une petite (voir même grosse) mise à jour d'un post que j'avais entrepris sur la copie de propriétés communes à deux classes de types différents.
Ce code est très pratique dans le cadre du découpage d'un projets en plusieurs couches (BLL, DAL, BO). Il permet de faire passer des données de la BLL vers l'application sans utiliser de classes de la BO. On peut alors construire une classe qui n'a en commun avec la BO que les propriétés communes avec l'interface (donc aucun élément en rapport avec l'aspect base de données).
Via le code suivant on peut effectuer les opérations suivantes :
- Créer un objet Class2 à partir d'un objet Class1.
- Copier les propriétés d'un objet Class1 vers un objet Class2 existant.
- Créer un tableau d'objets Class2 à partir d'un tableau d'objets Class1.
- Copier les propriétés d'un tableau d'objets Class1 vers un tableau d'objets Class2 existant.
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Tools { public static class GenericsExtensions { #region Copier des propriétés communes à 2 classes différentes /// <summary> /// Retourner un nouvel objet de type U à partir des propriétés commune au type T /// </summary> /// <typeparam name="T"></typeparam> /// <typeparam name="U"></typeparam> /// <param name="sender"></param> /// <returns></returns> public static U Copier<T, U>(this T sender) where U : new() { // Création d'une instance du type de retour U retour = new U(); // Copier les propriétés de l'orinal vers le retour sender.Copier<T, U>(retour); return retour; } /// <summary> /// Copie les propriétés du type U à partir des propriétés commune au type T /// </summary> /// <typeparam name="T"></typeparam> /// <typeparam name="U"></typeparam> /// <param name="sender"></param> /// <param name="retour"></param> public static void Copier<T, U>(this T sender,U retour) { var req = ( // Selection des properties de l'objet original from s in typeof(T).GetProperties() // Selection des properties de l'objet de retour from r in typeof(U).GetProperties() // Jointure des properties where r.Name == s.Name & r.PropertyType == s.PropertyType select new { r, s }) .ToArray(); // Test si on a bien des donnée if (req != null & req.Length > 0) { for (Int32 i = 0; i < req.Length; i++) { // req[i].r.SetValue( retour, req[i].s.GetValue(sender, null), null); } } } /// <summary> /// Retourner un nouveau tableau d'objet de type U à partir des propriétés commune au tableau du type T /// </summary> /// <typeparam name="T"></typeparam> /// <typeparam name="U"></typeparam> /// <param name="sender"></param> /// <returns></returns> public static U[] Copier<T, U>(this T[] sender) where U : new() { // Création d'une instance du type de retour U[] retour = new U[sender.Length]; for (Int32 i = 0; i < sender.Length; i++) { retour[i] = new U(); } // Copier les propriétés de l'orinal vers le retour sender.Copier<T, U>(retour); return retour; } /// <summary> /// Copie les propriétés du tableau de type U à partir des propriétés commune au tableau du type T /// </summary> /// <typeparam name="T"></typeparam> /// <typeparam name="U"></typeparam> /// <param name="sender"></param> /// <param name="retour"></param> public static void Copier<T, U>(this T[] sender, U[] retour) { var req = ( // Selection des properties de l'objet original from s in typeof(T).GetProperties() // Selection des properties de l'objet de retour from r in typeof(U).GetProperties() // Jointure des properties where r.Name == s.Name & r.PropertyType == s.PropertyType select new { r, s }) .ToArray(); // Test si on a bien des donnée if (req != null & req.Length > 0) { for (Int32 i = 0; i < sender.Length; i++) { for (Int32 j = 0; j < req.Length; j++) { // req[j].r.SetValue( retour[i], req[j].s.GetValue(sender[i], null), null); } } } } #endregion } }