3

所以我正在开发一个 GUI 库,我有 3 个类:UIElement,每个 UI 对象的基础,UIContainer,它实现了保存其他子元素的可能性和 UIRect,它实现了元素的位置和大小。现在我想创建一个同时使用 UIRect 和 UIContainer 的类。显然这是不可能的,但是这个问题有什么优雅的解决方案吗?

4

4 回答 4

4

这是一种可能性:从其中一个类继承(例如,UIRect),并嵌入另一个(例如,UIContainer)。实现 IUIContainerbu 将所有调用转发到嵌入对象的接口。

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);
    }
}

另一种可能是使用两个接口,通过扩展方法共享实现。

于 2013-05-24T14:08:34.020 回答
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 
 {
 }
于 2013-05-24T14:14:04.377 回答
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; } }
}
于 2013-05-24T14:16:45.440 回答
1

“使用接口和组合”的通用答案似乎有点矫枉过正。可能不需要使用接口——您不太可能扮演一个有时可以由 anUIRect有时由UIElement不是UIRect. 只需将 UIRect 类型的属性 rect 添加到您的 UIContainer。

更新

(评论后)我的答案的症结在于建议不要遵循制作接口并将调用委托给 UIRect 对象的私有实例的模式。

UIRect,从名字上看,有各种处理屏幕上矩形空间几何的数据和逻辑。这意味着:

  • 您可能不会有多个实现。一个欧几里得就足够了;
  • 您可能会发现有许多描述 UIContainer 的矩形:可能是边界框、转换前后的大小、插图等。

这只是我的判断,我没有很多数据。但据我所知,您需要一个简单的组合,而不是描述矩形属性的附加界面。

于 2013-05-24T14:16:11.420 回答