如何隐藏(删除)基类';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