1

Is there any simple way to convert/parse many Objects of Class Foo to objects of class Bar, using a member method of class Bar like Bar.loadFromFooObject(Foo classFoo) ?

So if I have those 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;
   }
}

So that I can avoid doing:

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

And do something like:

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

Is something like this possible using C# and/or Linq?

Vinz
  • 3,030
  • 4
  • 31
  • 52
  • Your code could be pseudo-code but `barObjs[i].loadFromFooObject` would raise a NRE. You can *probably* have a static method in your class `Bar` and call that to transform. – Habib Feb 27 '15 at 14:13

4 Answers4

3

Write a method TransformFooToBar and then use the linq, e.g.,

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

If you really want it to be a method on the Bar class, write an extension method, and then linq looks like this:

var barObjs = fooObjs.Select(n => n.TransformFooToBar()).ToArray(); 
EluciusFTW
  • 2,565
  • 6
  • 42
  • 59
  • You could even go one step further and write an overloaded extension method to extend the `IEnumerable` itself to call the above LINQ select statement. It would look like `var barObjs = fooObjs.TransformFoosToBars();` – ryanyuyu Feb 27 '15 at 14:21
  • It should be mentioned that if it's left as a static method, the first version can be written slightly more simply as: `fooObjs.Select( TransformFooToBar ).ToArray()`. Naturally if it's an extension method this will also work (provided the static class name is included). – Kyle Feb 27 '15 at 14:23
  • @ryanyuyu This seems to be interesting. Could you show that approach in an answer maybe? :) – Vinz Feb 27 '15 at 14:38
1

This something like this, all you need to create a ConvertToBar method which takes a Foo and returns a Bar.

var barObjs = fooObjs.Select(i=>ConvertToBar(i)).ToArray();
Kye
  • 5,919
  • 10
  • 49
  • 84
1

I use this strategy a lot for any kind of object conversion/mapping:

  • Create the function for a single object conversion
  • Create an overload accepting an IEnumerable (usually a List for me) and use LINQ .Select to convert the entire list into. It codes seamlessly since the single object conversion is, by definition, a Func. See this SO answer for more explanation on Funcs.

You can also get fancy with extension methods by creating a few extension methods in a static class. For you case specifically, the extension methods could look like this:

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

And you would call these methods like this:

var fooList = new List<Foo>();
var barEnumerable = fooList.ToBars();
Community
  • 1
  • 1
ryanyuyu
  • 6,366
  • 10
  • 48
  • 53
  • This in my opinion is a neat way to do it. Looks super clean in the code! Thank you a lot :) – Vinz Mar 02 '15 at 16:30
0

My preference (and it is just a personal preference) is to override the explicit cast operator and just cast from one type to the other. Combine that with Kye's answer to handle multiple objects.

Kevin
  • 157
  • 3