|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
How to define Type T for List<T> at runtimepublic 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 Webbert wrote:
Show quote > 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 Webbert wrote:
Show quote > I am looking for a way to do something similar to Take a look at System.Type.MakeGenericType to create a concrete Type from an > > 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>() ); > } > } unspecialized generic type. -cd 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() ); } } } } } Webbert wrote:
> Using your suggestion of MakeGenericType, I came up with the It's the right way to create instantiations of a generic type at runtime.> following demo. While this works, is it necessarily the best/correct > way to do it? 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 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 Show quote "Carl Daniel [VC++ MVP]" wrote: > Webbert wrote: > > 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 wrote:
> I provided the first method because, to the best of my knowledge, I am Yep, you're right - the ty pe parameters to a generic type must be > restricted from doing something like: > foreach ( Type xyz in aTypes ) > { > List<xyz> myvar = RetrieveList<xyz>(); > } compile-time constants, otherwise you have to go through Type.MakeGenericType(). -cd |
|||||||||||||||||||||||