Search code examples
c#inheritance.net-7.0c#-11.0default-interface-member

Why is my implemented Method from the Interface lost in the class?


I have a builder structure where I have a base interface that has everything implemented for every builder and then concrete interfaces for the specific methods.

Now I face the problem, that a certain method from the most basic interface is just lost in the class. My inheritance looks like this Interface -> Interface -> Interface -> Class If I use the class then some of the Methods from the interfaces just vanish.

public interface IBuilder{
   public string Build(){...}
}

public interface IBuilder<TSelf, TCreator> : IBuilder{
   public TSelf AddAttribute(string attributeName, string attributeValue){...} //This Method is lost in the class
}

public interface IEntityBuilder : IBuilder<IEntityBuilder, IBuilder>{
   //EntityBuidler specific Methods
   ...
}

public class EntityBuilder : IEntityBuilder{
   //AddAttribute is not available here
}

Somehow the methods from the IBuilder get lost in the class, but if I use IEntitybuilder instead of EntityBuilder then I could use these methods.

Why is it like that? Shouldn't the method be available anyway, even if it is not implemented?

I tried to implement the target method then in the further interfaces and wanted to direct it to the implementation in the base interface, but did that either wrong or it does not work as I want, because my IDE warned me about a self reference.


Solution

  • You are providing the default interface method implementation:

    public interface IBuilder<TSelf, TCreator> : IBuilder{
       public TSelf AddAttribute(string attributeName, string attributeValue)
       {...} <- this
    }
    

    If you want to call it in the EntityBuilder you will need either to explicitly implement it in the class:

    public class EntityBuilder : IEntityBuilder
    {
        public IEntityBuilder AddAttribute(string attributeName, string attributeValue)
        {
            return this;
        }
    }
    

    or (if you want to call it from another method) - cast the class to the interface:

    public class EntityBuilder : IEntityBuilder
    {
        public void Do()
        {
            (this as IEntityBuilder).AddAttribute("", "");
        }
    }
    

    Another option is to just delete the implementation from the interface and implement it in the class itself (personally I would go with this option):

    public interface IBuilder<TSelf, TCreator> : IBuilder{
       public TSelf AddAttribute(string attributeName, string attributeValue);
    }
    

    See also: