因此,出于某种原因,我正在测试C#和.NET VM的限制。我遇到了一些令人困惑的行为。
采用这些类和接口:
public interface ITest
{
void Test();
void Test2();
}
public abstract class Base : ITest
{
void ITest.Test()
{
Console.WriteLine("base");
}
public void Test2()
{
Console.WriteLine("base2");
}
public void Test3()
{
Console.WriteLine("base3");
}
}
public class Impl : Base, ITest
{
void ITest.Test()
{
Console.WriteLine("impl");
}
void ITest.Test2()
{
Console.WriteLine("impl2");
}
public void Test3()
{
Console.WriteLine("impl3");
}
}
然后像这样使用它们:
var i = new Impl();
var b = (Base)i;
var itest1 = (ITest)i;
var itest2 = (ITest)b;
itest1.Test();
itest2.Test();
itest1.Test2();
itest2.Test2();
i.Test2();
b.Test2();
i.Test3(); //for reference, a standard non-virtual method outside of an interface
b.Test3();
我希望输出看起来像这样:
impl
base
impl2
base2
impl2
base2
impl3
base3
但当然,事情不可能那么简单。所以,实际输出是这样的:
impl
impl
impl2
impl2
base2
base2
impl3
base3
除了这种疯狂的奇怪行为之外,是否可以访问Base.Test()实现?
答案 0 :(得分:2)
也许你应该检查一下为什么你会发现你变得奇怪的结果。对我来说,看起来你得到了你所实现的。
由于没有Base.Test
,无法获得Base.Test
。您需要通过界面明确地访问它,然后它不再是Base
,而是Impl
,因为底层真实对象不是Base
类型。
答案 1 :(得分:0)
Base
明确实施ITest.Test()
。它是一种实施方式,但它是"私有" 实施,只能通过ITest
界面访问。
最重要的是,Impl
重新实施 ITest.Test()
,所以当你尝试itest2.Test()
时,你会指出这个重新实现强>
这里的两个关键点是:
Base.Test()
。ITest.Test()
重新实施,杀死了Base
Impl
实施{{1}}实施的所有可能性。我建议稍微重命名一下这个问题:当派生类显式重新实现界面时,如何调用基接口显式实现?因为那是你要问的...... < / p>