mardi 30 août 2016

Design pattern to map derived types to list of new type

I have a list of derived types I want to map to a list of another type. Each derived type maps differently to the new type.

Is there any pattern to do this without casting each types and that keeps the logic of the mapping outside of the type (in a factory).

Here's an example, I'd like to find an alternative to GetFlatSwitch, something like GetFlat :

class Program
  {
    static void Main(string[] args)
    {
      List<Base> list = new List<Base>() { new DerivedA() { A = "A" }, new DerivedB() { B = "B" }};

      List<Flat> flatList = list.Select(x => Factory.GetFlat(x)).ToList(); // not working
      List<Flat> switchFlatList = list.Select(x => Factory.GetFlatSwitch(x)).ToList(); // works, but casting each element
    }

    static class Factory
    {
      public static Flat GetFlat(Base baseObj)
      {
        return new Flat();
      }

      public static Flat GetFlat(DerivedA a)
      {
        return new Flat() { A = a.A };
      }

      public static Flat GetFlat(DerivedB b)
      {
        return new Flat() { B = b.B };
      }

      public static Flat GetFlatSwitch(Base baseObj)
      {
        switch (baseObj.MyType)
        {
          case MyTypeEnum.A:
            DerivedA a = baseObj as DerivedA;
            return new Flat() { A = a.A };
          case MyTypeEnum.B:
            DerivedB b = baseObj as DerivedB;
            return new Flat() { B = b.B };
          default:
            return new Flat();
        }
      }
    }

    enum MyTypeEnum
    {
      A, B
    }

    abstract class Base
    {
      public abstract MyTypeEnum MyType { get; }
    }

    class DerivedA : Base
    {
      public override MyTypeEnum MyType
      {
        get
        {
          return MyTypeEnum.A;
        }
      }
      public string A { get; set; }
    }

    class DerivedB : Base
    {
      public override MyTypeEnum MyType
      {
        get
        {
          return MyTypeEnum.B;
        }
      }
      public string B { get; set; }
    }

    class Flat
    {
      public string A { get; set; }

      public string B { get; set; }
    }
  }

Aucun commentaire:

Enregistrer un commentaire