tags:

views:

136

answers:

5

Hi... i neeed something like this in C#.. have list in class but decide what will be in list during runtime

class A
{
    List<?> data;
    Type typeOfDataInList;
}

public void FillData<DataTyp>(DataTyp[] data) where DataTyp : struct
{
    A a = new A();
    A.vListuBudouDataTypu = typeof(DataTyp);
    A.data = new List<A.typeOfDataInList>();
    A.AddRange(data); 
}

Is this possible to do something like this ?

+4  A: 
class A<T>
{
    public List<T> data = new List<T>();
    public Type typeOfDataInList;

    public A()
    {
        typeOfDataInList = typeof(T);
    }

    public void Fill(params T[] items)
    {
        data.AddRange(items);
    }
}

If you don't know the type and have to use objects, declare an instance of A like this:

A<object> myClass = new A<object>();
myClass.Fill(new object(), new object());

Otherwise if you do know the type, you can do this:

A<int> myInts = new A<int>();
myInts.Fill(1, 2, 5, 7);
John JJ Curtis
Your fill method makes for a nice time to use the params keyword. Then your example could just be `myInts.Fill(1,2,5,7); `
Matthew Whited
@Matthew - Great suggestion, updated.
John JJ Curtis
I am waiting for one of the mystical future releases where params can be used with IEnumerable<> (I have no idea is MS is even looking at do think, let alone have a timeline.)
Matthew Whited
A: 

System.Collections.Generic.List<T> ?

Andrey
@Andrey: he/she doesn't know the type at compile time
Jeremy Bell
+3  A: 

Yes.

class A
{
    IList data;
    Type typeOfDataInList;
}

public void FillData<T>(T[] data) where T : struct
{    
    A a = new A();
    A.typeOfDataInList = typeof(T);
    A.data = new List<T>(data);
}

It would be better to make the A class generic:

class A<T>
{
    IList<T> data;
    Type typeOfDataInList;
}

public void FillData<T>(T[] data) where T : struct
{    
    A<T> a = new A<T>();
    a.typeOfDataInList = typeof(T);
    a.data = new List<T>(data);
}
SLaks
Thanks, that could work ...
Perry
+1  A: 

You might want to consider a generic class:

public class A<T> where T : struct
{
    public List<T> data;
    public Type type;
}

public void FillData<DataType>(DataType[] data) where DataType : struct
{
    A<DataType> a = new A<DataType>();
    a.data = new List<DataType>();
    a.AddRange(data);
}
LorenVS
+1  A: 

You are going to need to use reflection to instantiate an IList<T> where T is not known until runtime.

See the following MSDN article, which explains it better than I could (scroll down to the section on how to construct a generic type): http://msdn.microsoft.com/en-us/library/b8ytshk6.aspx

Here is a short example:

        Type listType = typeof(List<>);
        Type runtimeType = typeof(string); // just for this example
        // assert that runtTimeType is something you're expecting
        Type[] typeArgs = { runtimeType };
        Type listTypeGenericRuntime = listType.MakeGenericType(typeArgs);
        IEnumerable o = Activator.CreateInstance(listTypeGenericRuntime) as IEnumerable;
        // loop through o, etc..
Jeremy Bell
Or use an `ArrayList` or `List<Object>`.
SLaks
The difference being that with an ArrayList or List<Object>, the code may add heterogeneous types to the collection, whereas with an instantiated generic type will only allow objects of that type or a subclass to be added.
Jeremy Bell
This is where `IList` (the non-generic type) comes in very handy, without having to write lots of reflection code.
leppie
Well, I'm assuming the original poster will have code somewhere down the line that will do something with the data. At that time he will have to cast the objects to that concrete data type. If you use a List<object> or just a non-generic IList, you have to cast each item in the list to the concrete data type. If you use my method, you can safely cast the return value of Activator.CreateInstance to an IList<ConcreteDataType> and then access each item in the list without a cast.
Jeremy Bell