tags:

views:

109

answers:

5

I have generic type that looks like:

public class GenericClass<T, U> where T : IComparable<T>
{
    // Class definition here
}

I then have a collection of these instances. What is the cleanest way to pass through the type constraints?

public class GenericCollection<V> where V : GenericClass<T, U> // This won't compile
{
    private GenericClass<T, U>[] entries;

    public V this[index]
    {
        get{ return this.entries[index]; }
    }
}

Is there perhaps a better way to design this? I think that specifying

GenericCollection<T, U, V> where V : GenericClass<T, U> 

seems awkward. Might be my only option though....

+2  A: 

I think the collection will need the same constraints as GenericClass:

public class GenericCollection<T, U> where T : IComparable<T>
{
    private GenericClass<T, U>[] entries;
}
Lee
I tried that at first but I wanted to have a type-safe indexer. I updated the question to reflect that.
Brian Triplett
@Brian Why can you not have public GenericClass<T, U> this[int index]? How is that not type-safe?
juharr
You're right. type-safe is probably not the right word. I really want to avoid casting the GenericClass later if possible. In retrospect this solution is also valid. I probably should have stuck with my first answer.
Brian Triplett
A: 

you haven't declared it as a class!

public class GenericCollection<V>
BritishDeveloper
haha, good catch. updated the edit. That wasn't my issue though...
Brian Triplett
+4  A: 

When creating a generic class, all generic type parameters of all objects used in all members of the generic class must be resolvable at compile time.

You can have type parameters that are specific instances of other generic types - for example:

public class GenericCollection<T> where T : GenericClass<int, string> { ... }

But if you want the type parameters of GenericClass to be generic themselves, then all of those types need to be part of the class declaration, as you've written:

GenericCollection<T, U, V> where V : GenericClass<T, U> 

Sorry if it seems awkward, but that's your only option.

Aaronaught
Worth pointing out that the field being declared, `private GenericClass<T, U>[] entries`, should probably be written as `private V[] entries`. I don't think that the code will compile otherwise, the indexer property won't be valid without a cast.
Aaronaught
@Aaronaught You are correct. Thanks for pointing that out.
Brian Triplett
+1  A: 

I think your solution is

public class GenericClass<T, U> where T : IComparable<T>
{
     // Class definition here
}

public class GenericCollection<T,U>  where T : IComparable<T>
{
     private GenericClass<T, U>[] entries;
     public GenericClass<T, U> this[int index]
      {
         get{ return this.entries[index]; }
      }
}
Nix
+1  A: 

I think this is what you really want..

    class g<t, u> where t : IComparable<t>
{
}

class gc<t, u>
{
    private g<t, u>[] entries;

    public g<t, u> this[int index]
    {
        get { return this.entries[index]; }
    }
}
gbogumil