Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using C# interfaces while maximizing code reuse

So say I had a C# class,

class Foo : Bar, IBar, IBar2
{

}

... where Bar is a class, and IWhatever and IFine are interfaces. I plan to use a similar implementation of IWhatever and IFine across multiple classes- the only sane way I can see to encapsulate this code and reuse it across all the classes is to make a class Whatever that inherits from IWhatever and Fine that inherits from IFine and make them members of the class that implements those interfaces and then call their members in the members implemented from the interfaces, like so:

class Foo : Bar, IWhatever, IFine
{
   IWhatever mWhatever;
   IFine mFine;
   Foo()
   {
      mWhatever = new Whatever();
      mFine = new Fine();
   }
   // from IWhatever
   void Kick()
   {
      mWhatever.Kick();
   }
   // from IFine
   void Punch()
   {
      mFine.Punch();
   }
}

Am I doing it right? Is there a better way?

like image 951
fordeka Avatar asked Aug 10 '26 19:08

fordeka


2 Answers

When you are trying to implement the same multiple implementations across many classes via inheritance, that is a design smell. C#'s lack of multiple (class) inheritance is actually an asset, not a liability in this regard, because it enforces the single-responsibility principle.

Think of it this way: the two types of abstractions available in C# have two complementary forms of representing real-life entities.

  • Abstract class: "Is a"
  • Interface: "Does something" or "Has such and such qualities/behavior"

The implication of this is that interfaces should almost always be "hollow" because we assume that even though different classes may implement the same interface, it is likely that each one will do it differently.

Be careful about the use of inheritance. Remember the sage wisdom of the GOF:

Favor object composition over inheritance.

So getting back to the problem you're trying to solve, it might be better to do this:

public class Foo : Bar
{
   public IWhatever Whatever
   {
      get;
      private set;
   }

   public IFine Fine
   {
      get;
      private set;
   }

   public Foo(IWhatever whatever, IFine fine)
   {
      Whatever = whatever;
      Fine = fine;
   }
}

Now use an IOC container to inject concrete implementations of those interfaces. This is my humble recommendation.

like image 148
Jacobs Data Solutions Avatar answered Aug 12 '26 11:08

Jacobs Data Solutions


You can make it more general:

class Foo<TWhat, TFine> : Bar, IWhatever, IFine
    where TWhat : IWhatever, new()
    where TFine : IFine, new()
{
   IWhatever mWhatever;
   IFine mFine;
   Foo()
   {
      mWhatever = new TWhat();
      mFine = new TFine();
   }
   // from IWhatever
   public void Kick()
   {
      mWhatever.Kick();
   }
   // from IFine
   public void Punch()
   {
      mFine.Punch();
   }
}

This way, Foo can be made to use any classes which implement IWhatever and IFine, not just Whatever and Fine.

But whether you want to do that is up to you. I'd need more specific information before I could have an opinion on what the right structure for your code is.

like image 31
royh Avatar answered Aug 12 '26 10:08

royh



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!