Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generic List of Generic Interfaces not allowed, any alternative approaches?

Tags:

I am trying to find the right way to use a Generic List of Generic Interfaces as a variable.

Here is an example. It is probably not the best, but hopefully you will get the point:

public interface IPrimitive<T>
{
     T Value { get; }
}

and then in another class, I want to be able to declare a variable that holds a list of objects that implement IPrimitive<T> for arbitrary T.

// I know this line will not compile because I do not define T   
List<IPrimitive<T>> primitives = new List<IPrimitives<T>>;

primitives.Add(new Star());   // Assuming Star implements IPrimitive<X>
primitives.Add(new Sun());    // Assuming Sun implements IPrimitive<Y>

Note that the T in IPrimitive<T> could be different for each entry in the list.

Any ideas on how I could setup such a relationship? Alternative Approaches?

like image 547
P B Avatar asked Dec 23 '10 21:12

P B


People also ask

What are not allowed for generics?

Cannot Use Casts or instanceof With Parameterized Types. Cannot Create Arrays of Parameterized Types. Cannot Create, Catch, or Throw Objects of Parameterized Types. Cannot Overload a Method Where the Formal Parameter Types of Each Overload Erase to the Same Raw Type.

Can interfaces be generic?

A generic interface is primarily a normal interface like any other. It can be used to declare a variable but assigned the appropriate class. It can be returned from a method. It can be passed as argument.

Can a non generic class implement a generic interface?

It is possible to create a non-generic class that implements a generic interface, provided that the type parameters are provided.

How do I restrict a generic type in Java?

Java For Testers Whenever you want to restrict the type parameter to subtypes of a particular class you can use the bounded type parameter. If you just specify a type (class) as bounded parameter, only sub types of that particular class are accepted by the current generic class.


3 Answers

public interface IPrimitive {  }  public interface IPrimitive<T> : IPrimitive {      T Value { get; } }  public class Star : IPrimitive<T> //must declare T here {  } 

Then you should be able to have

List<IPrimitive> primitives = new List<IPrimitive>;  primitives.Add(new Star());   // Assuming Star implements IPrimitive primitives.Add(new Sun());    // Assuming Sun implements IPrimitive 
like image 182
Josh Avatar answered Oct 11 '22 18:10

Josh


John is correct.

Might I also suggest (if you are using C# 4) that you make your interface covariant?

public interface IPrimitive<out T>
{
     T Value { get; }
}

This could save you some trouble later when you need to get things out of the list.

like image 38
Andrew Hare Avatar answered Oct 11 '22 18:10

Andrew Hare


You say it won't work because you don't define T. So define it:

public class Holder<T>
{
    public List<IPrimitive<T>> Primitives {get;set;}
}
like image 38
John Saunders Avatar answered Oct 11 '22 17:10

John Saunders