Cannot implicitly convert MyType<Foo> to MyType<IFoo>

c#, contravariance, covariance, implicit-conversion

Solution

Yes this is a variance issue. You need to create an interface (only interfaces and delegates can be co/contravariant) `IPaginatedDto<out TDto>` where the `Dtos` cannot have a setter (otherwise you cannot use `out`):

public interface IPaginatedDto<out TDto> where TDto : IDto
{
    int PageIndex { get; set; }
    int PageSize { get; set; }
    int TotalCount { get; set; }
    int TotalPageCount { get; set; }
    bool HasNextPage { get; set; }
    bool HasPreviousPage { get; set; }
    IEnumerable<TDto> Dtos { get; }
}

And your `PaginatedDto<TDto>` will implement this interface:

public class PaginatedDto<TDto> : IPaginatedDto<TDto> where TDto : IDto
{

    public int PageIndex { get; set; }
    public int PageSize { get; set; }
    public int TotalCount { get; set; }
    public int TotalPageCount { get; set; }

    public bool HasNextPage { get; set; }
    public bool HasPreviousPage { get; set; }

    public IEnumerable<TDto> Dtos { get; set; }
}

And use the interface in your method:

private static void ProcessDto(IPaginatedDto<IDto> paginatedDto)
{

    //Do work...
}

Problem

I am not sure if this is a Covariance and Contravariance issue but I cannot get this working. Here is the code: ``` public interface IDto { } public class PaginatedDto<TDto> where TDto : IDto { public int PageIndex { get; set; } public int PageSize { get; set; } public int TotalCount { get; set; } public int TotalPageCount { get; set; } public bool HasNextPage { get; set; } public bool HasPreviousPage { get; set; } public IEnumerable<TDto> Dtos { get; set; } } public class PersonDto : IDto { public int Id { get; set; } public string Name { get; set; } public string Surname { get; set; } public int Age { get; set; } } class Program { static void Main(string[] args) { var people = new List<PersonDto> { new PersonDto { }, new PersonDto { }, new PersonDto { }, }; var paginatedPersonDto = new PaginatedDto<PersonDto>() { Dtos = people }; //ProcessDto doesn't accept this ProcessDto(paginatedPersonDto); } private static void ProcessDto(PaginatedDto<IDto> paginatedDto) { //Do work... } } ``` For some reason, I cannot pass `PaginatedDto<PersonDto>` as `PaginatedDto<IDto>` to `ProcessDto` method. Any idea how can I solve this issue?

Original source