Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / New Users / June 2006

Tip: Looking for answers? Try searching our database.

How to define Type T for List<T> at runtime

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Webbert - 13 Jun 2006 15:19 GMT
I am looking for a way to do something similar to

public void CreateList()
{
    Type[] dataTypes =
    {   
        typeof(int),                            typeof(string)
    };

    Dictionary<string, object> mylist = new Dictionary<string, object>();

    foreach ( Type y in dataTypes )
    {
        mylist.Add( y.Name, new List<y>() );
    }
}

For reference, I   ** WILL NOT **  be using the System.Data types.  I will
be using custom classes.

Thanks,
Dave
Carl Daniel [VC++ MVP] - 13 Jun 2006 15:33 GMT
> I am looking for a way to do something similar to
>
[quoted text clipped - 18 lines]
> Thanks,
> Dave
Carl Daniel [VC++ MVP] - 13 Jun 2006 15:34 GMT
> I am looking for a way to do something similar to
>
[quoted text clipped - 12 lines]
> }
> }

Take a look at System.Type.MakeGenericType to create a concrete Type from an
unspecialized generic type.

-cd
Webbert - 13 Jun 2006 17:06 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?

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

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.