2012-01-23 2 views
10

Supposons que vous avez 2 classes comme ceci:Y at-il quelque chose de construit dans .NET/C# pour copier des valeurs entre objets?

public class ClassA { 
    public int X { get; set; } 
    public int Y { get; set; } 
    public int Other { get; set; } 
} 

public class ClassB { 
    public int X { get; set; } 
    public int Y { get; set; } 
    public int Nope { get; set; } 
} 

Maintenant, imaginez que vous avez une instance de chaque classe et que vous voulez copier les valeurs d'un en b. Y a-t-il quelque chose comme MemberwiseClone qui copiera les valeurs où les noms de propriétés correspondent (et bien sûr est tolérant aux pannes - on a un get, et l'autre un ensemble, etc.)?

var a = new ClassA(); var b = new classB(); 
a.CopyTo(b); // ?? 

Quelque chose comme ça est assez facile dans une langue comme JavaScript.

Je suppose que la réponse est non, mais il y a peut-être aussi une alternative simple. J'ai écrit une bibliothèque de réflexion pour ce faire, mais si elle est intégrée à C#/.NET à un niveau inférieur, elle serait probablement plus efficace (et pourquoi réinventer la roue).

+2

jetez un oeil à AutoMapper: http://lostechies.com/jimmybogard/2009/01/23/automapper-the-object-object-mapper/ –

Répondre

10

Il n'y a rien dans le cadre pour le mappage objet-objet, mais il existe une bibliothèque très populaire qui fait ceci: AutoMapper.

AutoMapper est un simple petite bibliothèque construite pour résoudre un problème complexe trompeusement - se débarrasser de code mis en correspondance un objet à un autre . Ce type de code est plutôt morne et ennuyeux à écrire, alors pourquoi ne pas inventer un outil pour le faire pour nous?

Soit dit en passant, juste pour l'apprentissage, voici un moyen simple, vous pouvez mettre en œuvre ce que vous voulez. Je ne l'ai pas testé à fond, et il est loin d'être aussi robuste/flexible/performant comme AutoMapper, mais nous espérons il y a quelque chose pour sortir de l'idée générale:

public void CopyTo(this object source, object target) 
{ 
    // Argument-checking here... 

    // Collect compatible properties and source values 
    var tuples = from sourceProperty in source.GetType().GetProperties() 
       join targetProperty in target.GetType().GetProperties() 
            on sourceProperty.Name 
            equals targetProperty.Name 

       // Exclude indexers 
       where !sourceProperty.GetIndexParameters().Any() 
        && !targetProperty.GetIndexParameters().Any() 

       // Must be able to read from source and write to target. 
       where sourceProperty.CanRead && targetProperty.CanWrite 

       // Property types must be compatible. 
       where targetProperty.PropertyType 
            .IsAssignableFrom(sourceProperty.PropertyType) 

       select new 
       { 
        Value = sourceProperty.GetValue(source, null), 
        Property = targetProperty 
       }; 

    // Copy values over to target. 
    foreach (var valuePropertyTuple in tuples) 
    { 
     valuePropertyTuple.Property 
          .SetValue(target, valuePropertyTuple.Value, null); 

    } 
} 
-1

Pour autant que je sais que cela n'existe pas. La façon dont je l'ai fait est par:

public static T DeepCopy(T oldclass) 
{ 
    using (MemoryStream stream = new MemoryStream()) 
    { 
     BinaryFormatter formatter = new BinaryFormatter(); 
     formatter.Serialize(stream, oldclass); 
     ms.Position = 0; 
     return (T)formatter.Deserialize(stream); 
    } 
} 
1

Il n'y a rien comme ça dans .NET que je suis au courant, mais une bibliothèque qui est en mesure de le faire (et beaucoup plus) est AutoMapper. Pour votre cas, quelque chose comme:

_mapper.Map<A, B> (a, b); 
-1

Voir l'interface System.ICloneable, et la méthode System.Object.MemberwiseClone(). Comme indiqué dans les documents MSDN,

La méthode MemberwiseClone crée une copie superficielle en créant un nouvel objet, puis en copiant les champs non statiques de l'objet actuel sur le nouvel objet. Si un champ est un type de valeur, une copie bit à bit du champ est effectuée. Si un champ est un type de référence, la référence est copiée mais l'objet référencé ne l'est pas; par conséquent, l'objet original et son clone se réfèrent au même objet.
+0

Donc, vous dites que cela fonctionnerait? 'classB = classA.MemberwiseClone() en tant que classeB' –

Questions connexes