Replacing conditional type checking chains

Today, I came across some code similar to:

  if (myObject is MyClass1) 
     myOtherObject = new MyOtherClass1(myObject);
  else if (myObject  is MyClass2) 
     myOtherObject = new MyOtherClass2(myObject);
  else if (myObject  is MyClass3)
     myOtherObject = new MyOtherClass3(myObject);
  else if (myObject  is MyClass4)
     myOtherObject = new MyOtherClass4(myObject);
  else if (myObject  is MyClass5)
     myOtherObject = new MyOtherClass5(myObject);
  else if (myObject  is MyClass6) 
     // ...

It seems to me that this is somewhat difficult to maintain and would like to replace it with something less cumbersome. What are my options?

So far, I have been looking at a table-based approach using a dictionary, but I'm not sure if this is the best option.

// Not even sure this is valid syntax.
foreach (myClass in classes)
   if myObject is myClass
      new classes[myClass](myObject);

Any other ideas?

Update

Without going into many details here, this is the basic structure of classes:

MyBaseClass                              MyOtherBaseClass
  |                                        |
   -MyClass1                                -MyOtherClass1
  |                                        |
   -MyClass2                                -MyOtherClass2

MyBaseClass and its descendants are what I would call persistent data transfer objects. They store their data in a specific class format.

The closest I can describe MyOtherBaseClass and its descendants are unidirectional data cards [PoEAA] , but they mix a little business logic as well.

.

+3
2

generateOtherObject() MyClass1, MyClass2 .., ?

+5

.

, , ( , if-else/switch).

, MyOtherClass1, MyOtherClass2 MyOtherBaseClass, :

    public class YourTypeBuilderBuilder
    {
        private readonly static IDictionary<Type, Func<object, MyOtherBaseClass>> builderMap = new Dictionary<Type, Func<object, MyOtherBaseClass>>();

        static YourTypeBuilderBuilder()
        {
            /* Here is described the specific behavior 
            of the building of the requested type */

            builderMap.Add(typeof(MyClass1), obj => new MyOtherClass1((MyClass1)obj));
            builderMap.Add(typeof(MyClass2), obj => new MyOtherClass2((MyClass2)obj));
            builderMap.Add(typeof(MyClass3), obj => new MyOtherClass3((MyClass3)obj));
        }

        public static MyOtherBaseClass Build<T>(T input)
        {
            Func<object, MyOtherBaseClass> typeBuilder;
            bool hasTypeBeenFound = builderMap.TryGetValue(typeof(T), out typeBuilder);

            if (!hasTypeBeenFound)
            {
                throw new ArgumentException(string.Format("'{0}' is not a valid parameter.", typeof(T)));
            }

            // Let build the requested type
            MyOtherBaseClass obj = typeBuilder(input);

            return obj;
        }
    }

myOtherObject = YourTypeBuilder.Build(myObject);
+2

Source: https://habr.com/ru/post/1787578/


All Articles