How to fill a generics List with reflection?

M

MrNobody

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?
 
I

Ignacio Machin ( .NET/ C# MVP )

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?

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
 
M

MrNobody

Peter Duniho said:
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.
 
C

Chris Shepherd

MrNobody said:
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.
 
M

Marc Gravell

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
 
J

Jon Skeet [C# MVP]

MrNobody said:
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.
 
S

sergii Golik

// Get all properties on this object.
foreach (PropertyInfo pi in this.GetType().GetProperties())
{
List<BaseEntity> collection = (pi.GetValue(this, null) as List<BaseEntity>);
if (collection == null)
{
collection = Activator.CreateInstance(pi.PropertyType) as List<BaseEntity>;
}

Type itemType = pi.PropertyType.GetGenericArguments()[0];
// xElement its xml node with entity data
foreach (XElement itemElement in xElement.Elements())
{
BaseEntity item = Activator.CreateInstance(itemType) as BaseEntity;
item.ParseFromXElement(itemElement);
collection.Add(item);
}
}



MrNobod wrote:

How to fill a generics List with reflection?
13-May-08

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?

Previous Posts In This Thread:

How to fill a generics List with reflection?
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?

Re: How to fill a generics List with reflection?
On Tue, 13 May 2008 11:30:00 -0700, MrNobody


,



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

Re: How to fill a generics List with reflection?

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

public class MainClas

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 foun
list.Add(Activator.CreateInstance(listType)); // compiler error:
cannot convert form object to 'listType

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




public class ParentClas

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


public class MyClas

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.

Re: How to fill a generics List with reflection?
On Tue, 13 May 2008 12:39:01 -0700, MrNobody


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

Re: How to fill a generics List with reflection?
MrNobody wrote:

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.

Re: How to fill a generics List with reflection?

<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.

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

Re: How to fill a generics List with reflection?
On May 13, 2:30=A0pm, MrNobody <[email protected]>
wrote:
s
t
me.

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

Re: How to fill a generics List with reflection?
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


Submitted via EggHeadCafe - Software Developer Portal of Choice
Book Review: C# 4.0 In a Nutshell [O'Reilly]
http://www.eggheadcafe.com/tutorial...-a2da-88dde2e6d891/book-review-c-40-in-a.aspx
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top