C#与泛型相关的乐趣 - 相互依赖

时间:2010-03-19 21:05:44

标签: c# generics

作为一项实验,我正在尝试编写一个通用的MVP框架。

我开始时:

public interface IPresenter<TView> where TView: IView<IPresenter<...
{
    TView View { get; set;}
}

public interface IView<TPresenter> where TPresenter:IPresenter<IView<...
{
    TPresenter Presenter { get; set; }
}

显然这不起作用,因为无法解析TViewTPresenter的类型。你永远在写Type<Type<...。所以我的下一次尝试看起来像这样:

public interface IView<T> where T:IPresenter
{
    ...
}

public interface IView:IView<IPresenter>
{

}

public interface IPresenter<TView> where TView: IView
{
    ...
}

public interface IPresenter: IPresenter<IView>
{
    ...
}

这实际上是编译的,您甚至可以继承这些接口,如下所示:

public class MyView : IView, IView<MyPresenter>
{
    ...
}

public class MyPresenter : IPresenter, IPresenter<MyView>
{
    ...
}

问题出在类定义中,您必须定义两次在泛型类型中声明的任何成员。不理想,但它仍然编译。当您实际尝试从View访问Presenter的成员时,问题开始蔓延,反之亦然。当您尝试编译时,您会得到一个不明确的引用。从两个接口继承时,有没有办法避免成员的双重实现?甚至可以在编译时解析两个相互依赖的泛型类型吗?

3 个答案:

答案 0 :(得分:2)

这是编译,但我不确定它是要走的路。

public interface IPresenter<P, V> 
    where P : IPresenter<P, V>
    where V : IView<P, V>
{
}

public interface IView<P, V> 
    where P : IPresenter<P, V>
    where V : IView<P, V>
{
}

public class MyView : IView<MyPresenter, MyView>
{
}

public class MyPresenter : IPresenter<MyPresenter, MyView>
{
}

答案 1 :(得分:2)

我认为这里的问题是你不需要IViewIPresenter接口都是通用的 - 在MVP框架中,视图应该直接调用presenter来驱动表单(在这种情况下,视图对于某些演示者类型应该是通用的)或者视图应该完全不知道演示者并通过事件进行通信(在这种情况下,演示者应该是特定视图类型的通用)。

答案 2 :(得分:0)

您的视图应该采用模型的类型,比如TModel。主持人应该采取一种TView。我不认为应该有TPresenter。

相关问题