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

如何隐藏(删除)基类';C#中的s方法?,c#,inheritance,language-features,inheritance-prevention,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

问题的本质是,给定这样的类层次结构:

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();
    }
}
如何防止从类“B”继承的任何类看到方法
A.MethodToHide()
?在C++中,通过使用一个声明(如<代码>类B:私有A< /COD> >,这是很容易的,但是这个语法在C<.p/>中无效。 对于那些感兴趣的人(或者想知道我真正想做什么的人),我们要做的是为Rhino.Commons.NHRepository创建一个包装器,它隐藏了我们不想向我们的开发团队公开的方法,这样我们就可以用一种千篇一律的方式开发我们的应用程序,让新的开发人员可以轻松地遵循。因此,是的,我相信“Is-A”测试对整个链是有效的(WidgetRepository是一个BaseRepository是一个NHRepository)


编辑:为了论证起见,我应该提到类A是我们无法控制的API类。否则问题会变得相当容易。

如果您想定制一组功能,我想说的是您想制作一个包装器,而不是继承功能。我也不知道如何在C#中实现你的愿望


想想看,如果您控制范围之外的某个代码需要某个
NHRepository
实例。。。但是您已经从您的子类中删除了它所需的函数(您将发送该函数,因为这是您唯一的
NHRepository
实例)。一切都很顺利。这就是为什么我认为如果没有一些难看的黑客,甚至不可能做到这一点。

您在派生类B中的代码不会对所有派生类型隐藏基方法,只对其本身隐藏。您必须在基中将该方法设置为private。解决此问题的唯一方法是创建另一个不公开此方法的基类。

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

是专门解决当API不符合您的需要时如何使用框架的问题。

C没有在C++中有类似于受保护或私有继承的概念。 最好的选择是聚合类的一个实例,并公开用户有权访问的感兴趣的方法集


虽然在我看来,我认为这是不可能的,但是你可以考虑创建一个界面,它只展示你希望消费者使用的通用功能,以便在某些情况下你的包装可以替代它的集合。

< P>我不知道你可以在C++中做这件事,虽然我对C++不太了解。恐怕我同意Blix的说法,包装类可能就是我实现这一点的方式


简单地重写函数并在调用时抛出异常可能有效(但我不确定)

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

class A
{
    protected void MethodToExpose()
    {}

    [System.ComponentModel.EditorBrowsable(EditorBrowsableState.Never)]
    protected void MethodToHide(object param)
    {}
}

它实际上并不会消除这个功能,但如果他们只是你的内部人员。可能已经够近了。

据我所知,你不能以你想要的方式隐藏它。我认为你可以阻止它以任何实际的方式被使用,尽管:

class B : A
{
    public new void MethodToHide(object param)
    { 
        throw new DontUseThisMethodException();
    }

    protected void NewMethodInB()
    {}
}

但这不是最好的办法,所以你可能想用其他方法来解决这个问题……

实际上,如果你将B的方法定义为可从C访问,你可以对C隐藏A的方法


代码的唯一问题是在隐藏声明中使用了“private”。。。如果您使用protected或public,您将不会遇到任何问题,它将按照您的预期运行。我总是用字段来做这件事。

过时了它

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

[Obsolete("Reason", true)] // true will cause a compile-time error
[System.ComponentModel.EditorBrowsable(EditorBrowsableState.Never)]
设置可编辑或可浏览

(如前所述)

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

[Obsolete("Reason", true)] // true will cause a compile-time error
[System.ComponentModel.EditorBrowsable(EditorBrowsableState.Never)]
抛出异常

(如前所述)

在类B中,重写MethodToHide并引发异常

创建包装器

我认为迈克尔·梅多斯是对的。使用。这种模式还允许在单元测试时更容易地模拟代码

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

    protected void NewMethodInB()
    {
    }
}

在我看来,如果您只是想隐藏而不是真正覆盖和外部化一个新的函数,那么最好的方法就是添加一个EditorBrowsableState属性。 它隐藏了VisualStudio编辑器中的方法。任何试图使用它的人最终都会出现编译时错误

只需在方法的顶部添加以下代码:

[System.ComponentModel.EditorBrowsable(EditorBrowsableState.Never)]
比如说

public class User
{        
    public void DoSomething()
    {
       Something...
    }
}

public class Manager
{
    [System.ComponentModel.EditorBrowsable(EditorBrowsableState.Never)]
    public override void DoSomething()
    { }
}

void main()
{
   User user = new User();
   user.DoSomething();

   Manager manager = new Manager();
   manager.DoSomething(); // --------- This row will throw a design time error
}

祝你好运:)

+1我打赌我也会做包装,而不是继承。我认为最合适的做法是在抛出NotSupportedException的子类中重写或声明新方法,而不是专注于要隐藏的内容,而是专注于要公开的内容@Yoooder:我怀疑所有的方法都是虚拟的,所以它们不能被重写(重写可能会搞乱整个类的行为),并且试图用
new
隐藏它们似乎是他已经尝试过的(参见他的例子)。+1:我喜欢这个解决方案!只要开发人员坚持使用接口,并且不显式地将其转换为自定义类,他们就只能访问接口中指定的内容。这是一个巧妙的想法。这与我们已经在做的事情(使用NHibernate、MVC、依赖注入等)是一致的,因此我们已经有了存储库的接口(C类)。这使得C类的客户对封面下的内容一无所知。剩下要担心的就是C是如何实现的。在我们的例子中,将有许多“C”级的子类(不同对象的存储库)。所以我们的理想是B可能是a