0

I have a class:

[Serializable]
public class SaveObject
{
   public Dictionary<Type, List<BaseModel>> Tables { get; set; }
}

and a method which trying put a new list

public List<T> GetCollection<T>() where T : BaseModel
{
    if (saveObject.Tables == null)
        saveObject.Tables = new Dictionary<Type, List<BaseModel>>();

    List<T> repo = saveObject.Tables.FirstOrDefault(e => e.Key == typeof(T)).Value as List<T>;
    if (repo == null)
    {
        repo = new List<T>();
        saveObject.Tables.Add(typeof(T), repo);
    }

    return repo;
}

The problem is: Cannot convert from 'System.Collections.Generic.List<T>' to 'System.Collections.Generic.List<BaseModel>'

enter image description here

I don't understand why I cannot convert T to Base Model where I note in WHERE that T is BaseModel.

Kiro
  • 43
  • 1
  • 5
  • 1
    There's no inheritance relation between generic classes just because their type parameters have one. A List` is a different type from `Base`. Use *interfaces* instead of concrete containers – Panagiotis Kanavos Jul 16 '20 at 09:49
  • This is called [covariance](https://learn.microsoft.com/en-us/dotnet/standard/generics/covariance-and-contravariance) - in `List`, the T parameter isn't covariant which means that `List` can't be used in places where `List` is. On the other hand in [IEnumerable](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.ienumerable-1?view=netcore-3.1) the parameter *is* covariant. If you used `IList` you wouldn't have any problems – Panagiotis Kanavos Jul 16 '20 at 09:52
  • 1
    @PanagiotisKanavos [`IList`](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.ilist-1?view=netcore-3.1) has invariant type parameter, only `IEnumerable` is covariant – Pavel Anikhouski Jul 16 '20 at 09:56
  • How do you intend to use the contents of `saveObject.Tables` ? While the type parameters in `List` and `IList` aren't covariant, the parameters in `IReadOnlyList` and `IReadOnlyCollection` are. You could use one of those interfaces to store data. – Panagiotis Kanavos Jul 16 '20 at 09:57
  • @PavelAnikhouski `List` implements other covariant interfaces though - [IReadOnlyList](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.ireadonlylist-1?view=netcore-3.1) and [IReadOnlyCollection](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.ireadonlycollection-1?view=netcore-3.1) – Panagiotis Kanavos Jul 16 '20 at 09:57
  • @Kiro why not use `saveObject.Tables = new Dictionary>();`? Instead of `FirstOrDefault` you can use `Dictionary.TryGetValue(typeof(T),out var repo)`, eg `if(!tables.TryGetValue(typeof(T),out var repo){ tables.Add(typeof(T),new List());}` – Panagiotis Kanavos Jul 16 '20 at 10:11

0 Answers0