Search code examples
c#linqreadability

Convert/Parse many Objects using a member Method with less Code


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?


Solution

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