2015-02-27 1 views
1

est-il un moyen simple de convertir/analyser de nombreux objets de la classe Foo aux objets de la classe Bar, en utilisant une méthode de membre de la classe Bar comme Bar.loadFromFooObject(Foo classFoo)?Convert/Parse plusieurs objets à l'aide d'une méthode membre avec moins de code

Donc, si je les 2 classes:

class Foo 
{ 
    public string var1; 
    public int var2; 
    public List<string> var3; 
} 

class Bar 
{ 
    public string var1; 
    public int var2; 
    public float var4; 

    public void loadFromFooObject(Foo fooObj) 
    { 
     this.var1 = fooObj.var1; 
     this.var2 = fooObj.var2; 
    } 
} 

Alors que je peux éviter de faire:

Foo[] fooObjs = { new Foo(), new Foo(), new Foo()}; 
Bar[] barObjs = new Bar[fooObjs.Length]; 
for (int i = 0; i < fooObjs.Length; i++) 
{ 
    barObjs[i].loadFromFooObject(fooObjs[i]); 
} 

Et faire quelque chose comme:

Foo[] fooObjs = { new Foo(), new Foo(), new Foo()}; 
Bar[] barObjs = fooObjs.Parse(loadFromFooObject); 

est quelque chose comme ceci possible utilisant C# et/ou Linq?

+0

Votre code pourrait être pseudo-code, mais 'barObjs [i] .loadFromFooObject 'soulèverait un NRE. Vous pouvez * probablement * avoir une méthode statique dans votre classe 'Bar' et l'appeler pour la transformer. – Habib

Répondre

1

J'utilise cette stratégie beaucoup pour tout type de conversion de mapping objet /:

  • Créer la fonction pour une conversion unique objet
  • Créer une surcharge d'accepter une IEnumerable (généralement une liste pour moi) et Utilisez LINQ .Select pour convertir la liste entière en. Il code de manière transparente puisque la conversion d'un seul objet est, par définition, un Func. Voir this SO answer pour plus d'explications sur Func s.

Vous pouvez également vous amuser avec les méthodes d'extension en créant quelques méthodes d'extension dans une classe statique. Pour vous cas en particulier, les méthodes d'extension pourrait ressembler à ceci:

public static class ExtensionMethods 
{ 
    public static Bar ToBar(this Foo foo) 
    { 
     var bar = new Bar(); 
     bar.loadFromFooObject(foo); 
     //you could also move the logic to convert from the Bar class in here 
     return bar; 
    } 

    //Overload for a collection of Foos (like Foo[] or List<Foo>) 
    public static IEnumerable<Bar> ToBars(this IEnumerable<Foo> foos) 
    { 
     //Since ToBar is a Func<Foo, Bar> 
     return foos.Select(ToBar); 
     //alternate lambda syntax: return foos.Select(foo => foo.ToBar()); 
    } 
} 

Et vous appelez ces méthodes comme celle-ci:

var fooList = new List<Foo>(); 
var barEnumerable = fooList.ToBars(); 
+0

Ceci à mon avis est une manière soignée de le faire. On dirait super propre dans le code! Merci beaucoup :) – Vinzenz

1

Ceci quelque chose comme ceci, tout ce dont vous avez besoin pour créer une méthode ConvertToBar qui prend un Foo et retourne une barre.

var barObjs = fooObjs.Select(i=>ConvertToBar(i)).ToArray(); 
+1

Créer la méthode ConvertToBar dans quel contexte? – Vinzenz

+1

Je ne pense pas qu'il appartient à l'un ou l'autre objet. Créez-le dans une classe d'usine. – Kye

3

Ecrivez une méthode TransformFooToBar puis utiliser LINQ, par exemple,

var barObjs = fooObjs.Select(n => TransformFooToBar(n)).ToArray(); 

Si vous voulez vraiment que ce soit une méthode sur la classe Bar, écrire une méthode d'extension, puis LINQ ressemble ceci:

var barObjs = fooObjs.Select(n => n.TransformFooToBar()).ToArray(); 
+0

Vous pouvez même aller plus loin et écrire une méthode d'extension surchargée pour étendre le 'IEnumerable ' lui-même pour appeler l'instruction de sélection LINQ ci-dessus. Cela ressemblerait à 'var barObjs = fooObjs.TransformFoosToBars();' – ryanyuyu

+0

Il devrait être mentionné que si elle est laissée comme une méthode statique, la première version peut être écrite légèrement plus simplement: 'fooObjs.Sélectionnez (TransformFooToBar) .ToArray() '. Naturellement, si c'est une méthode d'extension, cela fonctionnera également (à condition que le nom de la classe statique soit inclus). – Kyle

+0

@ryanyuyu Cela semble être intéressant. Pourriez-vous montrer cette approche dans une réponse peut-être? :) – Vinzenz

0

Ma préférence (et il est juste une préférence personnelle) est de passer outre l'opérateur explicite coulé et juste jeter d'un type à l'autre. Combinez cela avec la réponse de Kye pour gérer plusieurs objets.