C# – share method logic along classes without inheriting from abstract class

cinheritanceinterfacesmultiple-inheritanceprogramming-logic

In some languages (e.g. C#) a class can only ever have 1 base class which seems like a problem for what I'm trying to do. I will give you an example of what i'm trying to do, hopefully this will make my problem clear.

I have got a lot of data objects, some of these data objects have an hierarchy, they can have a parent or a child. For these classes I created an abstract class which has 2 lists (1 of the parents and one of the children) it also has a few methods: AddChild(), AddParent(), RemoveChild(), RemoveParent().

quick example:

 Owner.AddChild(child):<br>
 Adds the child to the collection of childs of 'Owner'<br>
 It also adds 'Owner' to the collection of parents of 'child'.

To make sure all classes which have hierarchical components do this I created an abstract class which they all inherit so no one forgets to do it both ways.

I have also made a class for objects I want to update.
This is an abstract class not necessarily for the update part but for the equals part since I need all these classes to overwrite the Equals(object obj) method and GetHashcode() method and you cannot define an override in an interface (at lest not in C#)

Now clearly I'm going at this all wrong, thus my question how do I design my classes so they do get the functionality they need (and share with other classes) without creating an abstract class.

Best Answer

To make sure all classes which have hierarchical components do this I created an abstract class which they all inherit so no one forgets to do it both ways.

An interface would also "remind" developers to add those methods.

.. how do I design my classes so they do get the functionality they need (and share with other classes) without creating an abstract class.

If the amount of duplicative code is small or simple, use an interface and just force inheritors to write their own implementations. In your example, AddChild(), AddParent(), RemoveChild(), and RemoveParent() all seem pretty straightforward and simple to build.

But, if the implementations are difficult for you to repeat, you could provide an "inner" class (like TreeNode) for inheritors to wrap:

class DomNodeOrSomething<T> : ITreeNode
{
  private TreeNode data = new TreeNode<T>();

  void AddChild(T item)
  {
    data.AddChild(item);
  }

  void AddParent(T item)
  {
    data.AddParent(item);
  }

  void RemoveChild(T item)
  {
    data.RemoveChild(item);
  }

  void RemoveParent(T item)
  {
    data.RemoveParent(item);
  }
}

And, if that doesn't float your boat, use extension methods.

In the example from MS, a WordCount() method is added to the String interface. When this namespace is included, all String's will "automagically" have a .WordCount() method dangling off them.

namespace ExtensionMethods
{
    public static class MyExtensions
    {
        public static int WordCount(this String str)
        {
            return str.Split(new char[] { ' ', '.', '?' }, 
                             StringSplitOptions.RemoveEmptyEntries).Length;
        }
    }   
}

I believe you can do the same sort of thing for any interface. Something like:

namespace ExtensionMethods
{
  public static class TreeNodeExtensions
  {
    public static void AddChild(this ITreeNode self, ITreeNode item)
    {
      self.children.add(item);
    }
  }
}

This would still require that the ITreeNode interface force inheritors to provide common properties that the extension methods can manipulate.

Related Topic