所以我正在开发一个GUI库,我有3个类:UIElement,每个UI对象的基础,UIContainer,它实现了保存其他子元素的可能性,UIRect实现了元素的位置和大小。现在我想创建一个同时使用UIRect和UIContainer的类。显然这是不可能的,但这个问题有没有优雅的解决方案?
答案 0 :(得分:4)
这是一种可能性:继承其中一个类(比如UIRect
),然后嵌入另一个类(比如UIContainer
)。实现IUIContainer
bu的接口转发所有对嵌入对象的调用。
class UIRect {
...
}
interface IUIContainer {
IEnumerable<IUIElement> AllElements {get;}
void AddElement(IUIElement toAdd);
}
class UIContainer : IUIContainer {
public IEnumerable<IUIElement> AllElements {
get {
...
}
}
public void AddElement(IUIElement toAdd) {
...
}
}
class Multiple : UIRect, IUIContainer {
private readonly IUIContainer _cont = new UIContainer();
...
public IEnumerable<IUIElement> AllElements {
get {
return _cont.AllElements;
}
}
public void AddElement(IUIElement toAdd) {
_cont.AddElement(toAdd);
}
}
另一种可能性是使用两个接口,并通过扩展方法共享实现。
答案 1 :(得分:3)
您可以创建一个混合类,它接受UIElement,UIContainer,UIRect的实例作为属性,然后让您的子类实现混合并从那里获取它。
class HybridDerived : Hybrid
{
}
class Hybrid
{
public UIElement Element { get; set; }
public UIContainer Container { get; set; }
public UIRect Rect { get; set; }
}
class UIElement
{
}
class UIContainer
{
}
class UIRect
{
}
答案 2 :(得分:2)
C#通常倾向于使用组合而不是继承并使用接口进行通信。
示例:
public interface IUIElement
{
}
public interface IUIContainer
{
ICollection<IUIElement> Children;
}
public interface IUIRect
{
IPosition Position { get; }
ISize Size { get; }
}
public abstract class UIElement : IUIElement
{
}
public class Multiple : UIElement, IUIContainer, IUIRect
{
private readonly ISize _size;
private readonly IPosition _position;
private readonly List<UIElement> _children = new List<UIElement>();
public Multiple()
{
}
public IPosition Position { get { return _position; } }
public ISize Size { get { return _size; }; }
public ICollection<IUIElement> Children { get { return _children; } }
}
答案 3 :(得分:1)
“使用界面和构图”的通用答案似乎有些过分。可能不需要使用界面 - 您可能不会有UIRect
有时可以播放的角色,有时候UIElement
可能不是UIRect
。只需将UIRect类型的属性rect添加到您的UIContainer。
<强>更新强>
(评论之后)我的答案的关键在于建议不要遵循创建接口的模式并将调用委托给UIRect对象的私有实例。
从名称来看, UIRect
具有处理屏幕上矩形空间几何的各种数据和逻辑。这意味着:
这只是我的判断,我没有太多数据。但是从我看来,你需要一个普通的合成,而不是一个描述矩形属性的附加接口。