javirs
javirs

Reputation: 1100

Sharing implementation of interfaces in C#

I have some interfaces that need some simple implementation, but I have a handful of them, like for instance (not actual code, just example)

interface ISelectable
{
  public bool IsSelected;
  public void Select();
}

public class Selectable : ISelectable
{
  public bool IsSelected {get;set}
  public void Select()=> IsSelected = true;
}

Then I might have IStorable, which allows storing stuff in the database, like:

public interface IStorable
{
    public void Store();
    ...
}
public class Storable : IStorable
{
    private stuff...
    public void Store() { storing code }
}

The question is:

I have

Actually... I have MORE of these classes. So the combinations grow fast.

As far as I know, the only way to share the code is to have a base class implement the interface, then your class inherits from this base class. Like:

public class GameCard : Selectable { ....

But this would mean that the only way to have a class that inherits the code for Selectable, and the code for Storable is to have a base class doing both, something like public class StorableAndSelectable: IStorable, ISelectable But this makes no sense, especially when you want to have different storing methods...

What's the proper way to have your classes share the implementation code of the interfaces it implements? Having the implementation for each of them in one file, and feeding this "file" to all classes that need it?

Upvotes: 0

Views: 874

Answers (2)

Andrii Khomiak
Andrii Khomiak

Reputation: 605

Starting from C# 8.0 you can have default method implementation in interface definition

interface IA
{
    void M() { WriteLine("IA.M"); }
}
class C : IA { } // OK

IA i = new C();
i.M(); // prints "IA.M"

https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-8.0/default-interface-methods

According to your classes you can do something like this

interface ISelectable
{
  public bool IsSelected;
  public void Select() => IsSelected = true;
}

Upvotes: 0

JonasH
JonasH

Reputation: 36541

I would consider if inheritance is the correct approach for such simple properties. There are some possible alternatives. Using inheritance to include functionality is called implemention inheritance and is generally frowned upon. For simple stuff like this it provides little benefit, and for more complicated logic it ties the derived class to the base class to tightly.

To store an object I would probably suggest the repository pattern, that way you do not need a special interface.

To handle things like if a object is selected, the easiest option is probably just to have a settable property in the interface: bool IsSelected {get;set;}. This is trivially implementable by all derived classes, there is no real advantage of a implementation of just that interface, at least not outside of testing/dummy objects.

In some cases you can use a Func<T, bool> to describe how to determine if some arbitrary type is selected. In some cases it might be useful to use composition, i.e. use a separate class to describe selection, and have your game objects contain a property of this class.

Upvotes: 1

Related Questions