简体   繁体   中英

Interface implementation with abstract class input parameters

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.

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 ie 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.

您的类实际上并不是从接口派生的,请向每个类中添加IHelper,如下所示:

public class BankAccountHelper : IHelper

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM