如何在C#中隐藏(删除)基类的方法?

Ogr*_*m33 18 c# inheritance language-features inheritance-prevention

问题的本质是,给定一个类层次结构如下:

class A
{
    protected void MethodToExpose()
    {}

    protected void MethodToHide(object param)
    {}
}

class B : A
{
    new private void MethodToHide(object param)
    {}

    protected void NewMethodInB()
    {}
}

class C : B
{
    public void DoSomething()
    {
        base.MethodToHide("the parameter"); // This still calls A.MethodToHide()
        base.MethodToExpose(); // This calls A.MethodToExpose(), but that's ok
        base.NewMethodInB();
    }
}
Run Code Online (Sandbox Code Playgroud)

如何防止从类"B"继承的任何类看到该方法A.MethodToHide()?在C++中,通过使用诸如的声明这很容易class B : private A,但是这种语法在C#中无效.

对于那些感兴趣的人(或者想知道我真正想做什么),我们要做的是为Rhino.Commons.NHRepository创建一个包装器,它隐藏了我们不希望暴露给我们的开发人员组的方法,因此我们可以采用千篇一律的方式开发我们的应用程序,新开发人员可以轻松遵循.所以是的,我相信"Is-A"测试对整个链(WidgetRepository Is-A BaseRepository Is-A NHRepository)是有效的.

编辑:我应该提到,为了论证,A类是我们控制范围之外的API类.否则问题变得相当容易.

Mic*_*ows 21

您不能这样做并保留层次结构.如果可能,您应该创建定义理想的接口,然后子类化基类并实现接口.在代码中仅引用接口(不是基类类型).

适配器模式是专为解决如何使用框架的问题,当它的API不符合您的需求正好排队.


Mon*_*ode 19

已过时

在B类中,重写MethodToHide并添加Obsolete属性

[Obsolete("Reason", true)] // true will cause a compile-time error
Run Code Online (Sandbox Code Playgroud)

设置EditorBrowsable

(如前所述)

在B类中,重写MethodToHide并添加EditorBrowsable属性

[System.ComponentModel.EditorBrowsable(EditorBrowsableState.Never)]
Run Code Online (Sandbox Code Playgroud)

抛出异常

(如前所述)

在B类中,重写MethodToHide并抛出异常.

创建包装器

我认为Michael Meadows是对的.使用适配器模式.此模式还允许在单元测试时更轻松地模拟代码.

class B: IInterface
{    
    protected void MethodToExpose()
    {
        A a = new A();
        a.MethodToExpose();
    }

    protected void NewMethodInB()
    {
    }
}
Run Code Online (Sandbox Code Playgroud)


Bli*_*ixt 14

如果你想自定义一组功能,我会说你想制作一个包装而不是继承功能.我不知道如何在C#中做你想做的事.

想一想,如果你控制之外的某些代码想要这个NHRepository实例的东西会怎么样......但是你已经从你的子类所需的函数中删除了它的功能(你会发送它,因为那是你唯一的NHRepository实例.)一切热潮.这就是为什么我认为没有一些丑陋的黑客甚至不可能做到这一点.

  • +1我打赌做一个包装器,而不是继承.您可以专注于您想要展示的内容,而不是专注于您想要隐藏的内容. (3认同)

Jak*_*son 6

如果您使用的是Visual Studio,则可以使用以下属性隐藏intelliprompt中的方法/属性:

class A
{
    protected void MethodToExpose()
    {}

    [System.ComponentModel.EditorBrowsable(EditorBrowsableState.Never)]
    protected void MethodToHide(object param)
    {}
}
Run Code Online (Sandbox Code Playgroud)

它实际上不会摆脱这个功能,但如果它们只是你的内部人.它可能足够接近.