C
C#2y ago
akaJB

✅ How do I deal with generic covariance and collections types?

Let's say I have osmething like the following:
public interface IBoxCollection<out T> : IBox
where T : IBox
{
public Dictionary<string, T> Collection { get; }
}
public interface IBoxCollection<out T> : IBox
where T : IBox
{
public Dictionary<string, T> Collection { get; }
}
I get the following error: Invalid variance: The type parameter 'T' must be invariantly valid on 'IBoxCollection<T>.Collection'. 'T' is covariant I've looked around on how to resolve this issue but haven't found anything. Is there an easy solution to this problem, or is there a pattern which will accomplish what I'm looking for?
4 Replies
ero
ero2y ago
IReadOnlyDictionary would probably work? A normal dictionary lets you both insert (in) and retrieve (out) values A readonly dictionary would only allow you to retrieve them
canton7
canton72y ago
The problem is that someone can do:
class BoxCollection<T> : IBoxCollection<T> { ... }

var x = new BoxCollection<string>();
IBoxCollection<object> y = x;
y.Collection["test"] = 3;
class BoxCollection<T> : IBoxCollection<T> { ... }

var x = new BoxCollection<string>();
IBoxCollection<object> y = x;
y.Collection["test"] = 3;
Now your BoxCollection<string>, whose dictionary can only contain strings, contains an int
akaJB
akaJBOP2y ago
Can you verify if I'm I misunderstanding something? It seems to not compile:
using System.Collections.Generic;

namespace Test
{
public interface IBox
{
}

public interface IBoxCollection<out T>
where T : IBox
{
IReadOnlyDictionary<string, T> Collection { get; }
}
}
using System.Collections.Generic;

namespace Test
{
public interface IBox
{
}

public interface IBoxCollection<out T>
where T : IBox
{
IReadOnlyDictionary<string, T> Collection { get; }
}
}
https://dotnetfiddle.net/v9UvPa
C# Online Compiler | .NET Fiddle
Test your C# code online with .NET Fiddle code editor.
canton7
canton72y ago
Ah yeah, IReadOnlyDictionary isn't covariant (Which is confusing, as IReadOnlyCollection and IReadOnlyList are)

Did you find this page helpful?