Create a custom user collection of collections

303 Views Asked by At

I need to create a generic collection of generic collections, that should contain a generic class. I've tried hard, but haven't found any answers.This is how my realizated collection looks like: https://github.com/Infatum/PMC-Data-Model/blob/master/WTF/Position.cs This is the collection of position of a generic class Point. I need to create an indexed collection of Positions called Matrix, indexed collection of Matrix called Container and an indexed collection of Containers, named Containers. Please, help me!

public class Matrix<T> : ICollection<T> where T : Position<T>
{
    protected ArrayList matrix;
    protected bool isReadOnly;

    public Matrix()
    {
        matrix = new ArrayList();
    }
// ...
}

The trouble : The type 'T' cannot be used as type parameter 'T' in the generic type or method 'Position'. There is no implicit reference conversion from 'T' to 'WTF.Point'

This is actually the task, that was given to me: https://docs.google.com/document/d/1ZYXXAjrh0OYNLUuFy0HT6ZuAzISIecE73cgA4QoRDlc/edit#heading=h.nwbuqfwpq3gk

1

There are 1 best solutions below

5
On

Your type constraint on T is recursive - which I don't think you want it to be. (And neither does the compiler: The constraint enforces T to be some sort of Position<T>. this means that Position<T> is actually Position<Position<T>> - which violates your type constraint on the generic argument of Position, it expects WTF.Point instead of Position)

Solution:

public class Matrix<T> : ICollection<Position<T>>

But let me elaborate this a little more: In a sense, you want something like

public class Matrix<T> : ICollection<T> where T : Position<U>

so there is no more recursion. You want T to be "some kind of Position". But now we would have a new problem: where does U (let's call it the "element-type") come from? You should use that as your generic type argument of Matrix:

public class Matrix<U> : ICollection<T> where T : Position<U>

Now, the constraint can be collapsed directly into the interface type, i.e. ICollection<Position<U>> giving exactly the solution I gave above (modulo names).