【发布时间】:2013-08-30 12:22:49
【问题描述】:
我需要调用一个抽象类实现的方法。但是编译器总是默认使用具体类的重载方法,因为签名只需要一个继承的类型。
看看代码:
-- 这显然是我正在使用的实际代码的一个大大简化的版本;)
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>
它有效。
【问题讨论】:
-
这看起来像是来自编译器重载解析器的错误......我错过了什么
-
如果可以的话,为什么你有一个利用基本类型的重载,然后假设该类型是 ModelA 进行调用?设置过载的方式,我可以给你一个 ModelB。
-
非常有效的问题@neoistheone。基本上我有一个正在请求的 IRepository
。交付了一个 ConcreteRepository 。现在在 Repository 接口上调用了一个 Insert 方法。即使它是逆变的,我也不能将 IRepository 转换为 IRepository 。因此,我必须将 IRepository 继承添加到具体存储库中。 -
我认为发生这种情况的原因是来自重载决议规则,特别是来自7.5.5.1 of the C# specification "如果 N 适用于 A(第 7.4.2.1 节),则声明的所有方法在 T 的基类型中从集合中删除。" 在这种情况下,有
ConcreteClass上的有效方法,并且您要调用的override方法实际上属于到基地AbstractClass<TModel>所以它被忽略了。编辑:重载规则也可能将这两种方法视为“同等适用”;不过不确定。 -
我同意@ChrisSinclair。但没想到抽象方法的实现竟然被认为是基类的!
标签: c#