1

I want to understand interface implementation because I have been having errors that doesn't make sense to me. I have this interface and 2 abstract classes:

public interface ICashBuddieHelper
{
    IHelper FilterOnContext(DbBuddieContext db);
    IHelper PrepareResultModel(InputModelBase message);
    IHelper SortSet();
    ResultModelBase ToResultModel(InputModelBase message);
}

public abstract class ResultModelBase
{
    ...
}

public abstract class InputModelBase
{
    ...
}

and I have two classes that implement this Helper interface but with more derived versions of the input parameters and return types which are abstract classes as shown above. I have implemented the IHelper interface with the following classes

public class BankAccountHelper : ICashBuddieHelper
{
    public ICashBuddieHelper FilterOnContext(DbBuddieContext db){...}
    public ICashBuddieHelper PrepareResultModel(BankAccountInputModel message){...}//error
    public ICashBuddieHelper SortSet(){...}
    public ResultModelBase ToResultModel(BankAccountInputModel message){...}//error
}

public class CashFlowHelper : ICashBuddieHelper
{
    public ICashBuddieHelper FilterOnContext(DbBuddieContext db){...}
    public ICashBuddieHelper PrepareResultModel(CashFlowInputModel message){...}//error
    public ICashBuddieHelper SortSet(){...}
    public ResultModelBase ToResultModel(CashFlowInputModel message){...}//error
}

From the code snippet above, you can see that two lines in the implementing classes give the error that says:

'CashFlowHelper' does not implement interface member 'ICashBuddieHelper.PrepareResultModel(InputModelBase)' 'CashFlowHelper' does not implement interface member 'ICashBuddieHelper.ToResultModel(InputModelBase)'

Please can someone tell me what I am doing wrong? I would like to understand my misunderstanding of interfaces. Surely I can use a more derived type in the place of an abstract class. I don't understand what the compiler is complaining about.

11
  • 1
    You're missing public in CashFlowHelper (in front of the interface method signatures). The interface requires that they're public. Commented Dec 27, 2017 at 6:58
  • Adding to @john's answer: if you want to hide interface member, make it explicit. For instance, void IMyInterface.DoSomething { }. Commented Dec 27, 2017 at 6:59
  • sorry john i didn't just add public while adding it here on stackoverlow. I will add that to it now. Thanks Commented Dec 27, 2017 at 6:59
  • 1
    FYI Your code appears to work fine. See fiddle. Sometimes when I'm implementing classes, etc. I press Ctrl+. and just hit Enter, and because I've gone too fast, I accidentally end up with a new class in the local namespace with the same name as a class in another namespace. Is there a chance you have done this? Or a chance that the implementation and interface refer to two distinct classes with the same name? Commented Dec 27, 2017 at 7:12
  • 1
    @JosephIzang The question in its current state is unclear as it is incomplete and would require too many questions to clarify what is being asked. Read How to Ask and then provide a minimal reproducible example that can be used to reproduce your problem, allowing us to better understand what is being asked. Commented Dec 27, 2017 at 7:21

2 Answers 2

2

Surely I can use a more derived type in the place of an abstract class. I don't understand what the compiler is complaining about.

Referenceing interface (C# Reference)

An interface contains only the signatures of methods, properties, events or indexers. A class or struct that implements the interface must implement the members of the interface that are specified in the interface definition.

note: emphasis mine

The interface is a contract that any derived class must follow.

The compiler makes no assumption between

ICashBuddieHelper PrepareResultModel(InputModelBase message);

and

public ICashBuddieHelper PrepareResultModel(BankAccountInputModel message)

regarless of BankAccountInputModel being derived from InputModelBase.

As far as the compiler is concerned those are two different definitions and that you broke the contract by not implementing the interface as defined. Hence the compile error.

where then can I use my derived type i.e BankAccountInputModel? Or rather how then do I use a base type in an interface and get to use a more derived version of that type?

One possibility you could consider is using Generics (C# Programming Guide), which is a whole other topic in itself but look at the following example that refactors the interface and uses your previously defined types.

public interface ICashBuddieHelper<T> where T : InputModelBase {
    ICashBuddieHelper<T> FilterOnContext(DbBuddieContext db);
    ICashBuddieHelper<T> PrepareResultModel(T message);
    ICashBuddieHelper<T> SortSet();
    ResultModelBase ToResultModel(T message);
}


public class BankAccountInputModel : InputModelBase {
    //...
}

public class BankAccountHelper : ICashBuddieHelper<BankAccountInputModel> {
    public ICashBuddieHelper<BankAccountInputModel> FilterOnContext(DbBuddieContext db) { return null; }
    public ICashBuddieHelper<BankAccountInputModel> PrepareResultModel(BankAccountInputModel message) {
        return null;
    }
    public ICashBuddieHelper<BankAccountInputModel> SortSet() { return null; }
    public ResultModelBase ToResultModel(BankAccountInputModel message) {
        return null;
    }
}

How every this may add more complexity than is necessary.

I suggest reviewing your design choices.

Sign up to request clarification or add additional context in comments.

Comments

0

Your classes don't actualy derive from the interface, add : IHelper to each of the classes, as in:

public class BankAccountHelper : IHelper

1 Comment

sorry again a mistake by me. Haven't slept for a bit probably. My apologies. I will change this now.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.