Search code examples
c#.netinterface

Explicitly implement a derived Interface in C#


I have some code I need to restructure. The code calls into some third-party (neighboring department on a different tech stack) methods to do execute some evaluations on some data. There are several of these methods, which work similarly on a technical level, but do different functional work, so they are hidden behind this interface.

public interface IExecutor : IDisposable
{
  public void Execute(string workingDirectory);
}

public interface IAlphaExecutor : IExecutor { }

public interface IBetaExecutor : IExecutor { }

// Alpha coming from the 3rd-party nuget and got wrapped like this
public class AlphaImplementation : Alpha, IAlphaExecutor
{
  public void Execute(string workingDirectory)
    => Alpha(workingDirectory);
}

Sharing the IExecutor base-interface allowed us to write some code around it (preparing data, montioring, switching async<->sync context) for the general case and then using the desired interface for the functional task we needed.

Now the department delivering those implementations changed some things up and ended with all of them being in one class. As it does some heavy work on initialization I'd like to also consolidate my wrapper-Implementations into one class (and have one instance of that class being managed by Autofac). However, as both interfaces, IAlphaExecutor and IBetaExecutor come form the same base interface I can't create multiple implementations of execute:

public class CollectedImplementation : AlphaAndBeta, IAlphaExecutor, IBetaExecutor
{
  public void Execute(string workingDirectory) => ... //Implements both Interfaces

  public void IAlphaExecutor.Execute(string workingDirectory) => ... // CS0539: not a member of interface
}

Is there a neat way around this? Or do I need to restructure my interfaces and the code around it. And if so, are there some initial design pitfalls we've fell for that led to this place?


Solution

  • Since the Execute function in IAlphaExecutor and IBetaExecutor was originally implemented from the IExecutor interface, the IExecutor interface kind of "owns" the function.

    When you implement the IAlphaExecutor interface, what you're actually doing under the hood is implementing the IExecutor interface as well as everything in the IAlphaExecutor interface. In your class, void IAlphaExecutor.Execute is the same as void IExecutor.Execute. Effectively, its being implemented "through" the IAlphaExecutor class.

    To get around this, you would have to copy the Execute method inside IExecutor into the IAlphaExecutor and IBetaExecutor interfaces.

    Instead of:

    public interface IExecutor
        : IDisposable
    {
        public void Execute(string workingDirectory);
        //anything else in the IExecutor interface not detailed in your question
    }
    public interface IAlphaExecutor : IExecutor { }
    public interface IBetaExecutor : IExecutor { }
    

    You would have:

    public interface IExecutor
        : IDisposable
    {
        //anything else in the IExecutor interface not detailed in your question
    }
    public interface IAlphaExecutor
        : IExecutor
    {
        public void Execute(string workingDirectory);
    }
    public interface IBetaExecutor
        : IExecutor
    {
        public void Execute(string workingDirectory);
    }
    

    If you have nothing else in your IExecutor interface, you could either leave if there for clarity or remove it and replace all occurrences of where it is implemented with the IDisposable interface.