Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can not figure out why this will not compile

Tags:

c#

.net

.net-4.0

I'm trying to understand why the following will not compile. The compiler complains on the line where CreatePresenter tries to set the View property:

Cannot implicitly convert type 'Sandbox.Program.MyView' to 'TView'.

I know the context of the assignment does not make sense, it's more for illustration. Any help would be great!

    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();
        }
    }
like image 302
Marco Avatar asked Feb 24 '23 22:02

Marco


2 Answers

On the line:

this.Presenter.View = new MyView();

you're trying to set a MyView object to a property of generic type TView (implementing IView).

This is wrong because MyView is different from TView so it can't be assigned.

EDIT:

To expand a bit...

You can assign a type to its interface e.g. :

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

but you can't assign an interface to one of its implementers e.g.:

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

Here you're doing something more convoluted, something like this:

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

That is clearly wrong.
In fact, even if TView and MyView implement the same interface, to allow this TView should inherit from MyView but that's not specified among the generic constraints, and so the compiler can't do any assumption.

Have a look also to davy8's answer for a clear example :)

like image 156
digEmAll Avatar answered Feb 27 '23 13:02

digEmAll


Imagine you have 2 more classes:

class MyView2 : IView
{
}

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

Then you try to construct a new ViewBase with those:

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

In that case, in your method:

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

this.Presenter.View is MyView2 which doesn't inherit from MyView, even though both of them implement IView

like image 32
Davy8 Avatar answered Feb 27 '23 12:02

Davy8