0

I have a typed interface which I want to pass as a parameter. But the compiler (or the runtime if I add an explicit cast) doesn't like that.

Interface/Class definitions:

interface IModel { ... }
class ActualModelA : IModel { ... }
class ActualModelB : IModel { ... }

interface IView<T> where T : IModel { ... }
class ActualViewA : IView<ActualModelA> { ... }
class ActualViewB : IView<ActualModelB> { ... }

Here is the method where it shall be passed to:

static void Test(IView<IModel> view) { ... }

static void Main()
{
    var view = new ActualViewA();
    
    Test(view); // fails at compile time 
    Test((IView<IModel>) view); // compiles, but fails at runtime
}

the compile error is Argument 1: cannot convert from 'ActualViewA' to 'IView<IModel>' which doesnt fully makes sense to me since ActualView implements IView<ActualModelA> and ActualModelA implements IModel.

What am I missing here? The Test() shall be able to receive an object of ActualViewA and ActualViewB.

clamp
  • 33,000
  • 75
  • 203
  • 299
  • 2
    In the same logic `IList` would be the same as `IList`, but what would happen if tried to do `list.Add(new Chicken);` on the list of cows that I view as a list of animals? I would advise to read up on contravariance and covariance. Depending on information not provided here there might be an easy fix (`interface IView ...`, but from the provided code it's impossible to tell if that would be allowed) –  Jul 19 '21 at 16:07

1 Answers1

1

This is because ActualViewA does not extend IView<IModel>, but "only" IView<ActualModelA>. To remedy this you can make Test a generic method with variation on the IModel. Like this:

static void Test<T>(IView<T> view) where T : IModel { ... }
Netråm
  • 453
  • 6
  • 12