简体   繁体   English

为什么子类需要实现父接口来隐藏C#中的父类方法之一?

[英]Why do a child class need to implement a parents interface to hide one of that parents methods in C#?

I found this behaviour while working with a third-party library where I needed to hide and change one of it's methods. 我在使用第三方库时发现了这种行为,我需要隐藏并更改其中一种方法。

I have the following setup: 我有以下设置:

interface IBaseInterface
{
    string MethodToHide();
}

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

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

Why is it that when I run the following: 为什么当我运行以下内容时:

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

the output is 输出是

BaseClass BaseClass的

, but when changing the ChildClass signature to ,但在将ChildClass签名更改为时

class ChildClass : BaseClass, IBaseInterface

, the output is ,输出是

ChildClass ChildClass

Why do I need to explicitly specify the interface for the BaseClass method to be hidden by the ChildClass? 为什么我需要显式指定ChildClass隐藏的BaseClass方法的接口?

You need to read a bit more about the difference between overriding and hiding : 您需要更多地了解覆盖隐藏之间的区别:

Link: Override versus Hide 链接: 覆盖与隐藏

In a nutshell: 简而言之:

Hiding (using the new) runs the method according to the variable's type. 隐藏 (使用new)根据变量的类型运行方法。
Overriding overrides the method and will only use the child's method. 覆盖会覆盖该方法,并且只会使用子方法。

Edit : 编辑

When you use an Interface variable: 使用Interface变量时:

var i = (IBaseInterface) (new ChildClass());

The compiler will search for the best match for the methods that are used by the interface. 编译器将搜索接口使用的方法的最佳匹配。
Because you declared the BaseClass to implement the interface, then its methods will be chosen. 因为您声明了BaseClass来实现接口,所以将选择其方法。

If the ChildClass doesn't explicitly implement the interface, then the compiler can't link the methods to the interface. 如果ChildClass没有显式实现接口,则编译器无法将方法链接到接口。 By its point of view the BaseClass just happens to have methods by the same name. 从它的角度来看, BaseClass恰好具有相同名称的方法。

When you explicitly declare that the ChildClass also implements the interface, then its methods will be the best choice. 当您明确声明ChildClass也实现了接口时,它的方法将是最佳选择。

You need to mark the MethodToHide as virtual in your BaseClass. 您需要在BaseClass中将MethodToHide标记为虚拟。 Then your ChildClass can override it. 然后你的ChildClass可以覆盖它。 See http://msdn.microsoft.com/en-us/library/9fkccyh4(v=vs.80).aspx for more details. 有关详细信息,请参阅http://msdn.microsoft.com/en-us/library/9fkccyh4(v=vs.80).aspx

I believe this is the relevant part of the spec: 我相信这是规范的相关部分:

10.6.3 Virtual Methods In a virtual method invocation, the run-time type of the instance for which that invocation takes place determines the actual method implementation to invoke. 10.6.3虚方法在虚方法调用中,进行该调用的实例的运行时类型决定了要调用的实际方法实现。 In a non-virtual method invocation, the compile-time type of the instance is the determining factor. 在非虚方法调用中,实例的编译时类型是决定因素。

So when you cast your original object to IBaseInterface. 因此,当您将原始对象转换为IBaseInterface时。 It determines that the type is BaseClass since that's the one that implements it and calls its method. 它确定类型是BaseClass,因为它是实现它并调用其方法的类型。 In the second example it resolves it to ChildClass and calls its method. 在第二个示例中,它将其解析为ChildClass并调用其方法。

Because the main-class implements the interface. 因为main-class实现了接口。 The child-class just defines a new method, which has nothing to do with the interface. 子类只定义了一个与接口无关的新方法。 In fact the child class hides the method - that's what 'new' does. 实际上,子类隐藏了这个方法 - 这就是'new'的作用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM