简体   繁体   中英

Call Method overloaded from abstract class

I need to call a Method of a an abstract class implementation. But the compiler always defaults to use the overloaded method from the concrete class, since the signature just requires an inherited type.

Just have a look at the code:

-- This is obviously a vastly simplified version of the actual code that I'm using ;)

public class ModelBase { }
public class ModelA : ModelBase { }
public interface IInterface<in TModel>
{
    void Do(TModel model);
}
public abstract class AbstractClass<TModel> : IInterface<TModel>
{
    public abstract void Do(TModel model);
}
public class ConcreteClass : AbstractClass<ModelA>, IInterface<ModelBase>
{
    public override void Do(ModelA model)
    {
        // I'd like to invoke this method
    }

    public void Do(ModelBase model)
    {
        // how do I invoke the method above??
        Do((ModelA)model);
    }
}

^^ This results in a recursion

What I've tried is:

((IClass<ModelA>)this).Do((ModelA)model);

^^ doesn't change anything

base.Do((ModelA)model);

^^ throws an error "Cannot call an abstract base member: 'AbstractClass.Do(ModelA)'"

How do I call the "public override void Do(ModelA model)" method?


btw. If I change the class to this

public class ConcreteClass : IInterface<ModelA>, IInterface<ModelBase>

it works.

Cast this to AbstractClass<ModelA> before call:

public void Do(ModelBase model)
{
    ((AbstractClass<ModelA>)this).Do((ModelA)model);
}

Use named parameters:

public class ConcreteClass : AbstractClass<ModelA>, IInterface<ModelBase>
{
    public override void Do(ModelA modelA) // change 'model' into 'modelA'
    {
        // I'd like to invoke this method
    }

    public void Do(ModelBase model)
    {
        // how do I invoke the method above??
        Do(modelA : (ModelA)model);
    }
}

Now, the compiler knows that you want to call the Do(ModelA) method and not the Do(ModelBase) method.

Try to implement the interface explicitly. From now on you can call the method IInterface<ModelBase>.Do(ModelBase model) only from a reference of type IInterface<ModelBase>

public class ModelBase { }
public class ModelA : ModelBase { }
public interface IInterface<in TModel>
{
    void Do(TModel model);
}
public abstract class AbstractClass<TModel> : IInterface<TModel>
{
    public abstract void Do(TModel model);
}
public class ConcreteClass : AbstractClass<ModelA>, IInterface<ModelBase>
{
    public override void Do(ModelA model)
    {
        Console.Write("Do - Override AbstractClass<ModelA> ");
    }

    void IInterface<ModelBase>.Do(ModelBase model)
    {
        Console.Write("Do - IInterface<ModelBase> ");
        Do(model as ModelA);
    }
}

void Main()
{
    var modelA = new ModelA();

    (new ConcreteClass() as IInterface<ModelBase>).Do(modelA); //output -> Do - IInterface<ModelBase> Do - Override AbstractClass<ModelA> 
    Console.WriteLine();
    new ConcreteClass().Do(modelA); //output -> Do - Override AbstractClass<ModelA> 
}

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