I have this simple class:
public class Program
{
private static void Main(string[] args)
{
ClassB<ClassA> objA = new ClassB<ClassA>();
ClassB<ITestA<MyDTO>> objB = new ClassB<ClassA>();
}
}
public class ClassB<T>
{
//some code
}
public interface ITestA<T>
{
//some code
}
public class MyDTO
{
//some code
}
public class ClassA : ITestA<MyDTO>
{
//some code
}
This line of code:
ClassB<ITestA<MyDTO>> objB = new ClassB<ClassA>();
is giving a compilation error:
Cannot implicitly convert type 'ClassB<ClassA>' to 'ClassB<ITestA<MyDTO>>
Since ClassA implements ITestA, I don't know why this would give a compilation error. Please help me understand what I am doing wrong.
Thanks, Esen
It's due to a rather complex feature of generics called variance.
Classes are invariant, which means that if you declare ClassB<T>
, then when creating an instance:
ClassB<T1> obj = new ClassB<T2>
Then T1
has to be exactly the same class as T2
.
You can use interfaces to get around this, eg change your code to the following and it'll compile:
...
public class Program
{
private static void Main(string[] args)
{
ClassB<ClassA> objA = new ClassB<ClassA>();
IClassB<ITestA<MyDTO>> objB = new ClassB<ClassA>();
}
}
public interface IClassB<out T> // <- note the out before T
{
//some code here
}
public class ClassB<T> : IClassB<T>
{
//some code here
}
...
In this case, IClassB
is declared as covariant, which means that it can handle being given a derived class of T
, rather than needing T
itself. There are risks around using covariance (and contravariance) though, which is why generic classes are invariant by default.