为什么子类需要实现parents接口来在C#中隐藏其中一个parents方法?

为什么子类需要实现parents接口来在C#中隐藏其中一个parents方法?,c#,inheritance,interface,C#,Inheritance,Interface,我在使用第三方库时发现了这种行为,我需要隐藏和更改其中一种方法 我有以下设置: interface IBaseInterface { string MethodToHide(); } class BaseClass : IBaseInterface { public string MethodToHide() { return "BaseClass"; } } class ChildClass : BaseClass { new pub

我在使用第三方库时发现了这种行为,我需要隐藏和更改其中一种方法

我有以下设置:

interface IBaseInterface
{
    string MethodToHide();
}

class BaseClass : IBaseInterface
{
    public string MethodToHide()
    {
        return "BaseClass";
    }
}

class ChildClass : BaseClass
{
    new public string MethodToHide()
    {
        return "ChildClass";
    }
}
为什么当我运行以下命令时:

var i = (IBaseInterface) (new ChildClass());
Console.WriteLine(i.MethodToHide());
输出是

基类

,但将子类签名更改为

class ChildClass : BaseClass, IBaseInterface
,输出为

儿童班


为什么我需要显式指定基类方法的接口以被ChildClass隐藏?

您需要在基类中将MethodToHide标记为virtual。然后您的子类可以覆盖它。有关更多详细信息,请参阅

我相信这是规范的相关部分:

10.6.3虚拟方法在虚拟方法调用中,运行时类型 这是一个什么样的例子 调用的发生决定了 实际方法实现 援引在非虚拟方法中 调用的编译时类型 这个例子是决定性的 因素


因此,当您将原始对象投射到IBaseInterface时。它确定该类型是基类,因为它是实现该类型并调用其方法的类型。在第二个示例中,它将其解析为ChildClass并调用其方法。

您需要阅读更多关于覆盖隐藏之间区别的内容:

链接:

简言之:

隐藏(使用新的)根据变量的类型运行方法。
重写重写该方法,并且只使用子方法

编辑

使用接口变量时:

var i = (IBaseInterface) (new ChildClass());
编译器将搜索接口使用的方法的最佳匹配项。
因为您声明了基类来实现接口,所以将选择它的方法

如果子类没有显式地实现接口,则编译器无法将方法链接到接口。从它的观点来看,基类正好有同名的方法


当您显式地声明子类也实现了接口时,它的方法将是最佳选择。

因为主类实现了接口。子类只是定义了一个新方法,它与接口无关。事实上,子类隐藏了该方法,“new”就是这么做的。

我认为OP明确要求隐藏,而不是重写。我不能这样做,因为基类是第三方封闭源代码库的一部分。我知道我可以做到,我在询问行为。是的,但我对行为感兴趣,在这种情况下,我不能忽略这个方法。在ChildClass的实例化中,它被转换到接口,而不是基类。那么为什么编译器选择的是基类的方法呢?因为编译器的最佳选择是基类,它显式地声明了方法属于接口。从编译器的角度来看,childclass恰好有一个同名的方法。我在回答中添加了更多关于这个的内容,但是I.GetType().GetInterfaces().Contains(typeof(IBaseInterface))返回true,即使childclass没有显式指定IBaseInterface。如果不在子类上指定接口,它不应该工作吗?它确实实现了接口。但是子级中声明的方法没有链接到接口。它从基类继承接口。接口的方法链接到父方法,因为它显式声明要实现接口。