鉴于这种情况:
interface Interfaz
{
void M1();
}
abstract class ClaseAbstracta : Interfaz
{
public void M1() { }
public abstract Boolean M2();
}
class ClaseConcreta : ClaseAbstracta
{
public override Boolean M2() { return false; }
public virtual void M3(Int32 i) { }
public void M4() { }
}
我也这样做:
ClaseConcreta concretaCast = (ClaseConcreta) abst;
可以静态分析concretaCast.M2()
吗?
首先,它有override
所以看起来不可能,但是当你看到M2()
它实际上是具体的实现时。
这是静态可分析的还是每次覆盖它都必须在运行时动态地执行它?
答案 0 :(得分:2)
我怀疑在一般情况下可以对此进行静态分析。考虑:
class ClaseConcreta2 : ClaseConcreta
{
public override Boolean M2() { return true; }
}
void Main()
{
var x = new ClaseConcreta2();
DoSomething(x);
}
void DoSomething(ClassAbstracta abst)
{
ClaseConcreta concretaCast = (ClaseConcreta) abst;
// okay, so it's a ClaseConcreta, but what kind?
}
答案 1 :(得分:1)
有时可能:
void DoNothingReally(ClaseAbstracta x)
{
ClaseConcreta y = new ClaseConcreta();
y.M2(); // Only possibly the implementation from ClaseConcreta.
ClaseAbstracta abst = y;
ClaseConcreta concretaCast = (ClaseConcreta) abst;
concretaCast.M2(); // Only possibly the implemenation from ClaseConcreta, but more work to figure this out.
x.M2(); // can't know where the implentation is from generally, but see below
}
void DoMoreNothing()
{
DoNothingReally(new ClaseConcreta());//the call x.M2() above will only possibly the implemenation from ClaseConcreta but lots of work to figure that out.
}
现在,另一个问题是实际是否会确定这一点。在写关于C ++的文章中,Bjarne Stroustrup谈到了编译器可以用非虚拟调用替换虚拟调用作为优化这一事实。我不知道在C ++中做了多少,没关系,如果C#做了什么。理论上这是可能的。
答案 2 :(得分:0)
我想我明白了。
我将在运行时进行动态分析。
原因是覆盖也是一种虚方法,因为任何从该类继承的方法也可以覆盖。