c# - 多个包装器 - 如何做?

标签 c# oop design-patterns mvvm wrapper

我有一个代表桌面窗口的 Window 类,其中一些可以通过包装器 (TitledWindow) 来命名,其中一些可以位于桌面窗口之上其他的,也通过包装器 (TopWindow)。

UML View

现在,我正在尝试为 Window 创建一个 View 模型,我希望它支持这三个接口(interface)(IWindowITitledWindowITopWindow)。它看起来像这样:

public class WindowViewModel : ITopWindow, ITitledWindow
{
    private readonly IWindow _window;

    public WindowViewModel(IWindow window)
    {
        _window = window;
    }

    public IntPtr Handle
    {
        get { return _window.Handle; }
    }

    public Boolean? IsTopmost
    {
        get
        {
            var thisTopWindow = _window as ITopWindow;
            if (thisTopWindow == null)
                return null;
            return thisTopWindow.IsTopmost;
        }
        set
        {
            var thisTopWindow = _window as ITopWindow;
            if (thisTopWindow != null)
                thisTopWindow.IsTopmost = value;
        }
    }

    public String Title
    {
        get
        {
            var thisTitledWindow = _window as ITitledWindow;
            return thisTitledWindow == null ? null : thisTitledWindow.Title;
        }
    }
}

这就是我获取 View 模型的方式:

public IList<WindowViewModel> OpenWindows
{
    get
    {
        var windowViewModels =
            from window in _windowEnumerator.EnumerateWindows()
            let titledWindow = new TitledWindow(window, _windowTitleReader)
            let topWindow = new TopWindow(titledWindow, _topmostManager)
            select new WindowViewModel(topWindow);
        return windowViewModels.ToList();
    }
}

问题是我只能获取层次结构中的第一个st包装器。

OpenWindows 中的所有窗口也是 ITopWindow,但不是 ITitledWindow,因为它将其包装在 私有(private)只读 字段(可能应该保持这种方式)。

我想到的唯一解决方案是引入一个将它们联合起来的类(例如TitledTopWindow),但我必须为窗口的每个变体制作它,这太困惑了(尤其是稍后当我引入新的包装器来引入新功能时)。

正确的做法是什么?

更新:
在我的搜索中,我读到您使用包装器来扩展功能,但不扩展 API(这是这里的目标)。

因此,如果这个问题无法按照我的预期方式得到解决,我该如何以这种方式添加功能?

最佳答案

我的建议类似于

 class Window
 {
     List<object> traits;  

     T GetTrait<T>() 
     {
        return traits.Where(t => t.GetType() == typeof(T)).FirstOrDefault();
     } 
 }

 Window w;
 var topLevel = w.GetTrait<TopLevel>();
 if (topLevel != null)....

但是这个建议需要对接口(interface)/代码进行认真的修改。

我认为您确实想要类似以下无效代码的东西,这样您就可以添加任意数量的包装器,并且仍然让所有接口(interface)在最终类上可见:

 class TopLevel<T> : T where T:Window

我认为您无法直接实现这一点(因为您无法从其模板参数派生模板类)。

一种解决方法是在运行时生成派生类,添加必要的接口(interface)并代理内部类实现的所有接口(interface)。 Dynamically creating a proxy class中讨论/链接的可能方法(即这个 A simple Dynamic Proxy )。

关于c# - 多个包装器 - 如何做?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19621874/

相关文章:

c++ - 混合模板和非模板访问者方法

c# - 我是否应该密封所有我知道不应该用作基类的类?

c# - Visual Studio 无法打开 cshtml 文件

java - 如何在 java 中实现委托(delegate)模式(如在 objective-c 中)

访问实例方法时的 JavaScript OO 问题

python - 在Python中只读取一次配置信息

.net - 具有事件溯源的领域模型

c# - Visual Studio 类图查看器独立

c# - Json 没有以所需的模式返回正确的值

oop - "Fluent interfaces"维护调用链中的顺序