Using your suggestion of MakeGenericType, I came up with the following demo.
While this works, is it necessarily the best/correct way to do it?
Thanks,
Dave
==================
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
namespace ConsoleApplication1
{
class Program
{
Dictionary<string, object> mylist = new Dictionary<string, object>();
private List<object> sampleData = new List<object>();
private Type[] dataTypes =
{
typeof(int),
typeof(string)
};
static void Main( string[] args )
{
Program p = new Program();
p.CreateList();
p.FillList();
p.DiplayList();
Console.Out.WriteLine( "\n\nPress enter to continue..." );
Console.In.ReadLine();
}
public Program()
{
sampleData.Add( 1 );
sampleData.Add( "Hello" );
sampleData.Add( 2 );
sampleData.Add( "World" );
}
public void CreateList()
{
foreach ( Type type in dataTypes )
{
Type newList = typeof( List<> ).MakeGenericType( type );
BindingFlags internalFlags =
BindingFlags.CreateInstance |
BindingFlags.Public |
BindingFlags.Instance;
object instance = Activator.CreateInstance(
newList, internalFlags, null, null, null, null );
mylist.Add( type.Name, instance );
}
}
public void FillList()
{
Type listType;
IList list;
foreach ( object data in sampleData )
{
listType = data.GetType();
list = mylist[listType.Name] as IList;
if ( list != null )
{
list.Add( data );
}
}
}
public void DiplayList()
{
foreach ( string keys in mylist.Keys )
{
IList list = mylist[keys] as IList;
foreach ( object data in list )
{
Console.Out.WriteLine( data.ToString() );
}
}
}
}
}
Carl Daniel [VC++ MVP] - 14 Jun 2006 01:24 GMT
> Using your suggestion of MakeGenericType, I came up with the
> following demo. While this works, is it necessarily the best/correct
> way to do it?
It's the right way to create instantiations of a generic type at runtime.
The question I'd have is why go to the trouble to create strongly typed
lists when you're only ever accessing them in weakly typed way? You could
just use System.Collections.ArrayList everywhere and have significantly
simpler (although slightly less efficient) code.
Of course, if there's some other aspect to the real problem you're trying to
solve that benefits from having strongly typed containers, then there's
nothing wrong with this approach.
-cd
Webbert - 14 Jun 2006 12:45 GMT
I am doing a 2-way transformation between a 3rd party xml schema and my
system. Everything in their schema at the top level is optional which
basically turns into an object[]. With that in mind, I will have to iterate
over my list and put everything back into the object[]. So, I am providing 2
methods to work with.
One to iterate over an array of object types Type[] aTypes = {
typeof(string) ... }
foreach ( Type xyz in aTypes )
{
IList myvar = RetrieveList(xyz);
}
public IList RetrieveList( Type type )
{
return ( mylist[type.Name] as IList );
}
And one to use for tighter typing.
public List<T> RetrieveList<T>()
{
return ( mylist[typeof( T ).Name] as List<T> );
}
public List<Address> Address
{
get { return ( RetrieveList<Address>() ); }
}
I provided the first method because, to the best of my knowledge, I am
restricted from doing something like:
foreach ( Type xyz in aTypes )
{
List<xyz> myvar = RetrieveList<xyz>();
}
Thanks for your assistance.
Dave
> > Using your suggestion of MakeGenericType, I came up with the
> > following demo. While this works, is it necessarily the best/correct
[quoted text clipped - 12 lines]
>
> -cd
Carl Daniel [VC++ MVP] - 14 Jun 2006 14:59 GMT
> I provided the first method because, to the best of my knowledge, I am
> restricted from doing something like:
> foreach ( Type xyz in aTypes )
> {
> List<xyz> myvar = RetrieveList<xyz>();
> }
Yep, you're right - the ty pe parameters to a generic type must be
compile-time constants, otherwise you have to go through
Type.MakeGenericType().
-cd