C
C#17mo 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
ero17mo 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
canton717mo 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
akaJBOP17mo 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
canton717mo ago
Ah yeah, IReadOnlyDictionary isn't covariant (Which is confusing, as IReadOnlyCollection and IReadOnlyList are)
Want results from more Discord servers?
Add your server