8

我需要调用抽象类实现的方法。但是编译器总是默认使用具体类的重载方法,因为签名只需要一个继承的类型。

看看代码:

-- 这显然是我正在使用的实际代码的一个大大简化的版本;)

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>

有用。

4

3 回答 3

9

在调用之前投射thisAbstractClass<ModelA>

public void Do(ModelBase model)
{
    ((AbstractClass<ModelA>)this).Do((ModelA)model);
}
于 2013-08-30T12:39:05.740 回答
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)方法。

于 2013-08-30T12:35:16.590 回答
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> 
}
于 2013-08-30T12:58:20.483 回答