1

Suppose we have a class that implements an interface

class MyParaClass : IMyParaInterface

And another class named MyObject which takes generic T

class MyObject<T> where T: IMyParaInterface

Now I have a method that accepts this parameter

Print(MyObject<IMyParaInterface> parameter)

When I get an object which type is MyObject<MyParaClass>, and try to pass this to Print method,Build fails because it can not convert MyObject<MyParaClass> to MyObject<IMyParaInterface>

I thought there should be not an issue as MyParaClass implements IMyParaInterface.How to solve this or get around?

Joe Farrell
  • 3,502
  • 1
  • 15
  • 25
zheng yu
  • 297
  • 3
  • 10
  • @E_net4 thanks for reminding, it is c# – zheng yu Aug 08 '18 at 15:13
  • What exact error does the compiler throw? – Mathias R. Jessen Aug 08 '18 at 15:15
  • 1
    Possible duplicate of [Generics and casting - cannot cast inherited class to base class](https://stackoverflow.com/questions/3528821/generics-and-casting-cannot-cast-inherited-class-to-base-class). This variation uses an interface rather than a base class, but the underlying issue is the same. – Jeroen Mostert Aug 08 '18 at 15:37

1 Answers1

2

You should define your Print method as a template method:

void Print<T>(MyObject<T> parameter) where T : IMyParaInterface {}

Which means, that the method would take any MyObject<> instance, whose type argument implements your IMyParaInterface interface.

The problem with your original Print() code is, that it only accepts MyObject< IMyParaInterface > as input. Note, that MyObject< MyParaClass > is not instance of type MyObject< IMyParaInterface >.

There is another solution, where you can use .net's Covariance / contravariance features, by defining an interface for your object, where the type parameter will be marked as covariant (out T).

public interface IMyObject<out T> where T: IMyParaInterface {}

public class MyObject<T> : IMyObject<T> where T: IMyParaInterface {}


public static void Print(IMyObject<IMyParaInterface> parameter)  {}

In this case, MyObject< MyParaClass > will be type-compatible with IMyObject< IMyParaInterface >.

You can read about covariance / contravariance here: https://learn.microsoft.com/en-us/dotnet/standard/generics/covariance-and-contravariance

Gergely Hamos
  • 401
  • 4
  • 9