locked
Combining two similar classes into one. RRS feed

  • Question

  •         Hello,
    This is probably a "newbie" question. I have two very similar (large classes). All of the methods and code are the same (except as noted below). I originally coded them separately since some of the methods take different classes as method arguments. Something like this:

    public class One
    {
        SomeClass1 data;
        ...
       
         public void method1 (SomeClass1 data)
         {
              this.data = data;  // for use in other methods
     
              data.stuff = 1;
              ...
         }
    }


    public class Two
    {
        SomeClass2 data;
        ...

        public void method1 (SomeClass2 data)
         {
              this.data = data;  // for use in other methods
     
              data.stuff = 1;
              ...
         }
    }

    Note the the fields within SomeClass1 & SomeClass2 (i.e. data.stuff) that I need access to within classes One and Two are the same for SomeClass1 & SomeClass2. I want to combine the classes One and Two. What is the best way to do this in C#?

    I think, I could provide a base class for One and Two and extend One and Two with the specific methods I need, but the extended methods of both classes are identical and so I would need to maintain multiple separate identical (large/longish) methods. I am trying to avoid this.

        - Henrik


    Friday, November 14, 2008 6:23 PM

Answers

  • An abstract base class is probably the best for this.  With an abstract base class, you can implement all the methods that are identical in the abstract class, and then you can force the developer to create implementations of the non-identical methods.  Something like this:

    public abstract class MyAbstractBase
    {
        public abstract void DoSomethingSpecific();

        public void DoSomethingGeneral()
        {
            Console.WriteLine("SomethingGeneral");
        }
    }

    public class MySpecificClassOne : MyAbstractBase
    {
        public void DoSomethingSpecific()
        {
            Console.WriteLine("Something Specific One");
        }
    }

    public class MySpecificClassTwo : MyAbstractBase
    {
        public void DoSomethingSpecific()
        {
            Console.WriteLine("Something Specific Two");
        }
    }

    In the example above, the implementation of DoSomethingSpecific must differ from class to class, and must be implemented in every class that inherits from MyAbstractBase, whereas DoSomethingGeneral is non-specific to the implementations of MyAbstractClass, so the implementation resides in the code for MyAbstractBase. 

    For both of these classes, you can pass them around and use them as MyAbstractBase types, and any calls on their members will reflect the implementation of the instantiated type.  For instance:

    MyAbstractBase myClass = new MySpecificClassTwo();
    myClass.DoSomethingGeneral(); // calls the only version of DoSomethingGeneral.
    myClass.DoSomethingSpecific(); // calls the MySpecificClassTwo implementation of DoSomethingSpecific.

    I hope this helps.
    David Morton - http://blog.davemorton.net/
    Friday, November 14, 2008 6:30 PM
    Moderator
  • Use one class out of the two and have two method overloads to handle different operations. Make things simple for yourself, if the classes are alike, refactor and make it one class.
    Agility. http://salakoahmed.blogspot.com
    Friday, November 14, 2008 9:17 PM

All replies

  • An abstract base class is probably the best for this.  With an abstract base class, you can implement all the methods that are identical in the abstract class, and then you can force the developer to create implementations of the non-identical methods.  Something like this:

    public abstract class MyAbstractBase
    {
        public abstract void DoSomethingSpecific();

        public void DoSomethingGeneral()
        {
            Console.WriteLine("SomethingGeneral");
        }
    }

    public class MySpecificClassOne : MyAbstractBase
    {
        public void DoSomethingSpecific()
        {
            Console.WriteLine("Something Specific One");
        }
    }

    public class MySpecificClassTwo : MyAbstractBase
    {
        public void DoSomethingSpecific()
        {
            Console.WriteLine("Something Specific Two");
        }
    }

    In the example above, the implementation of DoSomethingSpecific must differ from class to class, and must be implemented in every class that inherits from MyAbstractBase, whereas DoSomethingGeneral is non-specific to the implementations of MyAbstractClass, so the implementation resides in the code for MyAbstractBase. 

    For both of these classes, you can pass them around and use them as MyAbstractBase types, and any calls on their members will reflect the implementation of the instantiated type.  For instance:

    MyAbstractBase myClass = new MySpecificClassTwo();
    myClass.DoSomethingGeneral(); // calls the only version of DoSomethingGeneral.
    myClass.DoSomethingSpecific(); // calls the MySpecificClassTwo implementation of DoSomethingSpecific.

    I hope this helps.
    David Morton - http://blog.davemorton.net/
    Friday, November 14, 2008 6:30 PM
    Moderator
  • Use one class out of the two and have two method overloads to handle different operations. Make things simple for yourself, if the classes are alike, refactor and make it one class.
    Agility. http://salakoahmed.blogspot.com
    Friday, November 14, 2008 9:17 PM