【发布时间】:2011-09-29 07:53:58
【问题描述】:
是的,我知道以前有人问过并回答过这个问题,但没有完全解决几个问题。
参考文献
基本上,我想从Control 派生,但不暴露某些属性。就我而言,我正在设计一个Container,它将包含许多Elements,以编程方式排列。我希望(并且可能要求)Element 派生自 Control,以便获取所有绘图和事件,但也能够将 Element 对象添加到 @ 987654329@ 的 Children 集合(原因很明显)。
唯一的问题是,如果Element 派生自Control,那么它的Location 属性就会暴露出来,用户可以很容易地破坏程序化放置。当然,我的直觉是保留 Control 附带的所有好东西并隐藏/禁用 Location。
我知道以下几点:
- 这违反了 SOLID Liskov 替换原则(按合同设计)
- 以前有人问过这个问题
- 我可以将
Control封装在我的Element中,并将所有呼叫转发给Control的所有呼叫- 这将是一项荒谬的工作,而且没有真正的收获。
- 封装的
Element仍然不能与Control类型兼容,并且不能在Control的派生形式的许多情况下使用。
我觉得这个(看似)反复出现的问题必须有一些更优雅的解决方案。提前谢谢!
编辑
我看到的唯一方法是:
public class Element : Control
{
public new Point Location { get; private set; }
}
但是,我有一个问题,我的容器类如何设置Elements 位置?在 C++ 中,人们会使用一个朋友类。我想如果我将这个控件保留在它自己的程序集中,我可以将设置器标记为internal。
编辑
对于那些想要这样做的人,我的解决方案是:不这样做。相反,我制作了一个自定义对象并自己实现了所有的点击/拖动等。尝试使用控件太复杂了,同时排除了位置等功能。
【问题讨论】: