无法弄清楚为什么这不会编译

时间:2011-03-01 20:31:30

标签: c# .net .net-4.0

我试图理解为什么以下内容无法编译。编译器在CreatePresenter尝试设置View属性的行上抱怨:

  

无法将类型'Sandbox.Program.MyView'隐式转换为'TView'。

我知道作业的背景没有意义,更多的是为了说明。任何帮助都会很棒!

    interface IView {
    }

    class Presenter<T> where T : IView {
        public T View { get; set; }
    }

    class MyView : IView {
    }

    class MyPresenter : Presenter<MyView> {
        public MyPresenter() { }
    }

    class ViewBase<TPresenter, TView>  
        where TPresenter : Presenter<TView>, new()
        where TView : IView {

        public TPresenter Presenter { get; private set; }

        void CreatePresenter() {
            this.Presenter = new TPresenter();
            this.Presenter.View = new MyView();
        }
    }

3 个答案:

答案 0 :(得分:7)

在线:

this.Presenter.View = new MyView();

您正在尝试将MyView对象设置为泛型TView的属性(实现IView)。

这是错误的,因为MyViewTView不同,因此无法分配。{/ p>

修改

扩大一点......

可以为其界面指定一个类型,例如:

IView v = new MyView(); // OK !

但你不能为其中一个实施者分配一个接口,例如:

IView v = ...;
MyView myView = v; // WRONG !

在这里,你正在做一些更复杂的事情,比如:

        IView
   _______|_______
  |               |
  |               |
TView    <--   MyView

这显然是错误的。
实际上,即使TViewMyView实现了相同的接口,也允许此TView继承MyView但是在通用约束中没有指定,因此编译器不能做任何假设。

还要看davy8's answer一个明确的例子:)

答案 1 :(得分:1)

想象一下,你还有两个班级:

class MyView2 : IView
{
}

class MyPresenter2 : Presenter<MyView2>
{
    public MyPresenter2() { }
}

然后尝试使用以下内容构建一个新的ViewBase:

var viewBase = new ViewBase<MyPresenter2, MyView2>();

在这种情况下,在您的方法中:

void CreatePresenter()
{
    this.Presenter = new TPresenter();
    this.Presenter.View = new MyView();
}

this.Presenter.View MyView2不会从MyView继承,即使它们都实现了IView

答案 2 :(得分:0)

MyView不保证属于同一类型TView。您可以使用此通用类的IView实现多个MyViews

如果您将ViewBase更改为以下代码,则至少会编译。我不确定它会如何影响您的应用程序的行为。

class ViewBase<TPresenter, TView>
    where TPresenter : Presenter<TView>, new()
    where TView : IView, new()
{

    public TPresenter Presenter { get; private set; }

    void CreatePresenter()
    {
        this.Presenter = new TPresenter();
        this.Presenter.View = new TView();
    }
}