我需要调用一个抽象类实现的方法。但是编译器总是默认使用具体类中的重载方法,因为签名只需要一个继承类型。
看看代码:
- 这显然是我正在使用的实际代码的简化版本;)
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);
}
}
^^这会导致递归
我尝试的是:
((IClass<ModelA>)this).Do((ModelA)model);
^^不会改变任何东西
base.Do((ModelA)model);
^^抛出错误“无法调用抽象基类成员:'AbstractClass.Do(ModelA)'”
如何调用“public override void Do(ModelA model)”方法?
顺便说一句。 如果我将课程改为此
public class ConcreteClass : IInterface<ModelA>, IInterface<ModelBase>
它有效。
答案 0 :(得分:9)
在致电之前将this
投放到AbstractClass<ModelA>
:
public void Do(ModelBase model)
{
((AbstractClass<ModelA>)this).Do((ModelA)model);
}
答案 1 :(得分:4)
使用命名参数:
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);
}
}
现在,编译器知道您要调用Do(ModelA)
方法而不是Do(ModelBase)
方法。
答案 2 :(得分:3)
尝试显式实现接口。从现在开始,您只能从类型IInterface<ModelBase>.Do(ModelBase model)
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>
}