The type argument must match exactly. IProvider<IContent> is a different type than IProvider<FileContent> , there is no inheritance between them.
Imagine you have an IProvider<IContent> ppp from your IProvider<FileContent> , and the developer is trying ppp.addContent(someOtherContentThatIsNoFileContent) . This operator is valid for IProvider<IContent> , but it violates type safety, therefore, such a conversion cannot be allowed.
Covariance and contravariance for type type parameters allow something similar under certain circumstances, but since your interface uses the type parameter as an output parameter, it will not apply to it as it is declared right now.
EDIT: Look at the IEnumerable definition:
public interface IEnumerable<out T>
So, you know that IEnumerable uses T only as an output parameter (you cannot add elements, just list them), and the out keyword indicates that T is covariant. So you can do
IEnumerable<String> strings = new List<String>(); IEnumerable<Object> objects = strings;
If you want to do this, you will have to remove the add method from your interface. The same applies to input parameters and the in keyword for type parameters.
Your interface will now look like this:
public interface IProvider<out T> where T : IContent { T getContent(int i); }
source share