0

Here is my current code (.net core):

Box code:

class Box { }

SpeicalBox code:

class SpecialBox : Box { }

Stack code:

interface Stack<T> where T : Box 
{
    AnotherInterface<T> TheFunction();
}

SpecialStack code:

class SpecialStack : Stack<SpecialBox> { }

StacksHolder code:

class StacksHolder
{
    private List<Stack<Box>> Stacks = new List<Stack<Box>>();
}

This is the error i get:

I am getting the following error if I am trying to add a SpecialStack to the list of Stacks in the StacksHolder:

cannot convert from 'SpecialStack' to 'Stack'

The code I use for that:

class StacksHolder
{
    private List<Stack<Box>> Stacks = new List<Stack<Box>>();

    public StacksHolder()
    {
        Stacks.Add(new SpecialStack());
    }
}

Does anyone have an idea why that does not work? I would be very happy if anyone could explain me, how to fix it.

Thanks in advance!

Panagiotis Kanavos
  • 120,703
  • 13
  • 188
  • 236
Tobias Etter
  • 744
  • 1
  • 6
  • 19
  • 6
    With the code you've given you can fix it by making `Stack` covariant i.e. `interface Stack where T : Box`. However your real `Stack` interface might have operations that will prevent you being able to make this change – Lee Sep 11 '19 at 12:36
  • @Lee thanks for your response. unfortunately I have operations in the `Stack` and therefore need it invariantly valid. – Tobias Etter Sep 11 '19 at 12:43
  • 4
    @TobiasEtter for starters, use a different name. [Stack](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.stack-1?view=netcore-3.0) is a common .NET collection defined in the *same* namespace as List. Interfaces should start with an `I` too. Even you will have trouble reading this code a week from now – Panagiotis Kanavos Sep 11 '19 at 12:49
  • 2
    As for the error, a `SpecialStack` is *not* a `Stack`. There's no inheritance relation between them. If you want to store both in the same list you'll have to make the interface covariant. If you have other operations modify them accordingly. If you have specific requirements explain them in the question itself – Panagiotis Kanavos Sep 11 '19 at 12:51
  • 2
    Possible duplicate of [Cannot convert from List to List](https://stackoverflow.com/questions/45349582/cannot-convert-from-listbar-to-listfoo) – Peter B Sep 11 '19 at 12:53
  • @PanagiotisKanavos Thanks for your response. I will keep that in mind for my next projects and optimize my current code for a better readability. – Tobias Etter Sep 11 '19 at 12:54
  • 2
    @TobiasEtter please explain what those other operations are. You can't *not* use covariance if you want to store those types in the same location. The question can't be answered the way it is right now – Panagiotis Kanavos Sep 11 '19 at 13:00
  • I could fix the problem by using the `out` keyword as @Lee suggested. Only adding the `out` keyword to the `Stack` interface did not help. In addition I had to add it to the other interface (`AnotherInterface`). @Lee please add your solution and I will accept it. – Tobias Etter Sep 11 '19 at 13:01

1 Answers1

1

I could fix my problem by adding the out keyword to both interfaces Stack and AnotherStack.

Thank you @Lee for bringing me to the solution!

Solution Code:

Stack code:

interface Stack<out T> where T : Box 
{
    AnotherInterface<T> TheFunction();
}

AnotherInterface code:

interface AnotherInterface<out T> where T : Box
{
}
Tobias Etter
  • 744
  • 1
  • 6
  • 19