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 / Languages / C# / May 2008

Tip: Looking for answers? Try searching our database.

How to fill a generics List with reflection?

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
MrNobody - 13 May 2008 19:30 GMT
Say I have a class that has a generics List as follows:

public List<MyClass> myClassList = new List<MyClass>();

and I want to create another class which tries to add an element of MyClass
to that list, but it is not explicitly creating an instance of MyClass, but
instead using the Activator to  create an instance based on it's type name.

How can I accomplish this in C# using reflection?
Ignacio Machin ( .NET/ C# MVP ) - 13 May 2008 20:14 GMT
On May 13, 2:30 pm, MrNobody <MrNob...@discussions.microsoft.com>
wrote:
> Say I have a class that has a generics List as follows:
>
[quoted text clipped - 5 lines]
>
> How can I accomplish this in C# using reflection?

I don't see where is the problem, you can invoke your Add either by
reflection or simply casting the instance resulting of using Activator
to the correct type.
Or you can use Activator to create an instance of MyClass and then use
InvokeMember with the created instance
Peter Duniho - 13 May 2008 20:23 GMT
> Say I have a class that has a generics List as follows:
>
[quoted text clipped - 8 lines]
>
> How can I accomplish this in C# using reflection?

Well, you said you're already using Activator.  So isn't that using  
reflection?

Once you've got an instance of MyClass, it doesn't matter how you got it.  
You can add it to a List<MyClass> whether you used "new" or Activator.  
So, if you're having problems adding the instance to your list, it's  
because you're not creating the type you apparently think you are.

You should post a concise-but-complete code sample that demonstrates the  
problem you're having.  Make sure you're specific about what fails.

Pete
MrNobody - 13 May 2008 20:39 GMT
> You should post a concise-but-complete code sample that demonstrates the  
> problem you're having.  Make sure you're specific about what fails.
>
> Pete

Ok, here is a good test case to demonstrate what I am talking about:

public class MainClass
   {
       public void Test()
       {
           ParentClass parent = new ParentClass();
           Console.WriteLine(parent.myClassList.Count + " items");

           Type listType = Type.GetType("Tools.MyClass");
           List<listType> list = parent.GetType().GetField("myClassList");
// the type or namespace name 'listType' could not be found
           list.Add(Activator.CreateInstance(listType)); // compiler error:
cannot convert form object to 'listType'

           Console.WriteLine(parent.myClassList.Count + " items");
           
       }
   }

   public class ParentClass
   {
       public List<MyClass> myClassList = new List<MyClass>();
   }

   public class MyClass
   {
       public string testString = "";
   }

See how do I make a generic reference of that List? I think in Java you can
do something like List<?> so you dont need to explicitly specify type but I
cant figure out how to do it in C#.

See I need to get a reference to that List using reflection without
explicitly specifying it's type, since it's type could be anything. Then I
need to add a new instance of that type to the list, again without explicitly
specifying it's type.

It has to be completely dynamic so that I can create an instance of a user
specified type and Add it to a List of that type.
Peter Duniho - 13 May 2008 21:03 GMT
> [...]
> See how do I make a generic reference of that List? I think in Java you  
> can
> do something like List<?> so you dont need to explicitly specify type  
> but I
> cant figure out how to do it in C#.

I don't think you can do this in Java either.  "List<?>" is sort of like  
"List<T>" in C# where T is a type parameter, but in either case it's a  
compile-time thing used to declare a generic.  When you _use_ a generic,  
there has to be a real type there.

Do you really need your collection to be in a List<T>?  Again, since the  
main benefit of generics is a compile-time thing, if you don't know the  
type at compile time, it's not clear why you want to use List<T>.

In this particular example, I would just use an ArrayList, which is an  
untyped collection that otherwise behaves similar to List<T>.

If you think that you really need a List<T> here, it would be helpful if  
you could elaborate on that, including presenting a code example that  
actually demonstrates that requirement.  To do what you're asking  
literally I believe would at a minimum require using reflection again,  
instantiating the specific List<T> using Activator or similar, and then  
using reflection to invoke the appropriate Add() method.

But it seems to me that there's a strong likelihood that there's not  
really a literal need to use List<T>.  If you can provide a better  
question, it's like you'll get a better answer, including an explanation  
of an alternative approach that doesn't require reflection at all for the  
collection itself.

Pete
Chris Shepherd - 13 May 2008 21:03 GMT
> See how do I make a generic reference of that List? I think in Java you can
> do something like List<?> so you dont need to explicitly specify type but I
> cant figure out how to do it in C#.

List<T>. From your description I don't even think you need reflection.

Something like:

private void AddNewTolist<T>(List<T> toList)
{
   if (toList != null)
       toList.Add(new T());
}

Maybe I'm wrong, I don't have access to VS atm.

Chris.
Marc Gravell - 13 May 2008 21:48 GMT
Generics:

       public void Test()
       {
           ParentClass parent = new ParentClass();
           Console.WriteLine(parent.myClassList.Count + " items");
           Foo(parent.myClassList);
           Console.WriteLine(parent.myClassList.Count + " items");
       }
       public void Foo<T>(List<T> list) where T : new() {
           list.Add(new T());
       }

Marc
Jon Skeet [C# MVP] - 13 May 2008 21:55 GMT
> > You should post a concise-but-complete code sample that demonstrates the  
> > problem you're having.  Make sure you're specific about what fails.
>
> Ok, here is a good test case to demonstrate what I am talking about:

<snip>

Looks to me like ParentClass should be generic, at which point half the
problems go away.

Most of the point of generics is to give *compile-time* type safety. If
you're not going to get that benefit, you'll probably find it's easier
just to use ArrayList rather than messing around with reflection.

Signature

Jon Skeet - <skeet@pobox.com>
Web site: http://www.pobox.com/~skeet   
Blog: http://www.msmvps.com/jon.skeet
C# in Depth: http://csharpindepth.com


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.