tags:

views:

419

answers:

5

I am facing a problem with .NET generics. The thing I want to do is saving an array of generics types (GarphicsItem):

public class GraphicsItem<T>
{
    private T _item;

    public void Load(T item)
    {
        _item = item;
    }
}

How can I save such open generic type in an array?

Thx

A: 
List<GraphicsItem<T>>

Probably needs some Where love on your GraphicsItem.

DevelopingChris
A: 

If you want to store heterogeneous GrpahicsItem's i.e. GraphicsItem< X> and GrpahicsItem< Y> you need to derive them from common base class, or implement common interface. Another option is to store them in List< object>

aku
A: 

Are you trying to create an array of GraphicsItem in a non-generic method?

You cannot do the following:

static void foo()
{
  var _bar = List<GraphicsItem<T>>();
}

and then fill the list later.

More probably you are trying to do something like this?

static GraphicsItem<T>[] CreateArrays<T>()
{
    GraphicsItem<T>[] _foo = new GraphicsItem<T>[1];

    // This can't work, because you don't know if T == typeof(string)
    // _foo[0] = (GraphicsItem<T>)new GraphicsItem<string>();

    // You can only create an array of the scoped type parameter T
    _foo[0] = new GraphicsItem<T>();

    List<GraphicsItem<T>> _bar = new List<GraphicsItem<T>>();

    // Again same reason as above
    // _bar.Add(new GraphicsItem<string>());

    // This works
    _bar.Add(new GraphicsItem<T>());

    return _bar.ToArray();
}

Remember you are going to need a generic type reference to create an array of a generic type. This can be either at method-level (using the T after the method) or at class-level (using the T after the class).

If you want the method to return an array of GraphicsItem and GraphicsItem, then let GraphicsItem inherit from a non-generic base class GraphicsItem and return an array of that. You will lose all type safety though.

Hope that helps.

AlexDuggleby
+2  A: 

Implement a non-generic interface and use that:

public class GraphicsItem<T> : IGraphicsItem
{
    private T _item;

    public void Load(T item)
    {
        _item = item;
    }

    public void SomethingWhichIsNotGeneric(int i)
    {
        // Code goes here...
    }
}

public interface IGraphicsItem
{
    void SomethingWhichIsNotGeneric(int i);
}

Then use that interface as the item in the list:

var values = new List<IGraphicsItem>();
Omer van Kloeten
A: 

First of all thanks for all answers. As Aku and Gidion pointed out it it not possible to use a non-generic class. In my project I also cannot use the Interface approach, as T can also be value-types like int and float.

The last one is a nice solution, event it is a bit hacky. But it works and I don't have to create an IF- Statement all on the which checks the type of T.

Thanks

ollifant