Instantiate complete object through reflection

E

Ericd

I am trying to perform a funciton that is best described as instantiating a
class and its complete list of subclasses by reflection. I would like to
pass this newly instantiated class (that does not have its subclasses
instantiated) into a routine that instantiates all subclasses.

Say this class as a class hierarchy as follows and each class has a
constructor with no paramters:

MyClass
SubClass1
SubClass2
SubSubClass1
SubClass3

I understand how to traverse the classes by utilizing GetType.GetNestedTypes
and also being able to create a new object of one of these subclasses using
Activator.CreateInance but the part that I am not comprehending is how I can
use this information to instantiate the classes in my original passed in
class so by the end of the routine all of its contained subclasses have been
instantiated.

Ultimately I really would like to be able to pass in a string of the "root"
class (be it the main or subclass) and instantiate all of its subclasses.
Then by passing in a name of a property in one of these classes to be able
to set it by name with a passed in value. These are secondary desires but
the inital full instantiate of all classes is my current block.

Thanks for any help you can provide.
 
J

Jon Skeet [C# MVP]

Ericd said:
I am trying to perform a funciton that is best described as instantiating a
class and its complete list of subclasses by reflection. I would like to
pass this newly instantiated class (that does not have its subclasses
instantiated) into a routine that instantiates all subclasses.

You seem to be a bit confused on two aspects:

1) Nested types aren't subclasses. There's no implicit inheritance
hierarchy between a nested type and its outer type.

2) When you create an instance of a type, that has no bearing on
derived types or nested types. There's no real concept of an instance
"that does not have its subclasses instantiated".

I think it would perhaps be useful to see a more concrete example of
what you want (with code). If you could show us the complete class
hierarchy, and the manual code that you want a reflective equivalent
of, we're more likely to be able to help.
 
P

Patrice

Most often it's best to describe what you are trying to do in a non
technical way in case someone would have a different approach to the problem
(for example if this is to reinstantiate something from values you have,
serialization could be another and perhaps better solution) rather than to
directly ask about the solution you came up with. Why do you have to do that
"by hand" ?

Also it could be perfectly legitimate to have an object instance with some
properties (is this what you meant by subclasses ?) not set so it's lkkely
not something you could apply to all classes ? (for example if you want to
apply this on class you have control on, it could be still done another way
etc...)
 
E

Ericd

This pseudocode hopefully makes it more understandable in what I am
attempting it to do.

The classes/subclasses:

Public Class MyClass
Public Class SubClass1
End Class

Public Class SubClass2
Public Class SubSubClass1
End Class
End Class

Public Class SubClass3
End Class
End Class


The "code":
Public Sub InstantiateAllObjects(ByRef InstantiatedObject AS MyClass)
IF InstantiatedObject.SubClass1 IS NOTHING THEN
InstantiatedObject.SubClass1 = NEW MyClass.SubClass1
IF InstantiatedObject.SubClass2 IS NOTHING THEN
InstantiatedObject.SubClass2 = NEW MyClass.SubClass2
IF InstantiatedObject.SubClass2.SubSubClass1 IS NOTHING THEN
InstantiatedObject.SubClass2.SubSubClass1 = NEW
MyClass.SubClass2.SubSubClass1
IF InstantiatedObject.SubClass3 IS NOTHING THEN
InstantiatedObject.SubClass3 = NEW MyClass.SubClass3
End Sub

To summarize my request. I would like to be able to pass in an object that
is defined as the above MyClass then through reflection "walk" the
class/subclass hierarchy and instantiate all of its subclasses. At the end
of the routine the object will all of its subclasses instantiated so that
properties (not shown) can be set within these classes. I will know the
type of object that I will be passing in so that end will not need to be
totally generic.
..........
 
J

Jon Skeet [C# MVP]

Ericd said:
This pseudocode hopefully makes it more understandable in what I am
attempting it to do.

Well, sort of.
The classes/subclasses:

Right. You don't actually have any subclasses there. You have nested
types, which are completely different.
Public Class MyClass
Public Class SubClass1
End Class

Public Class SubClass2
Public Class SubSubClass1
End Class
End Class

Public Class SubClass3
End Class
End Class


The "code":
Public Sub InstantiateAllObjects(ByRef InstantiatedObject AS MyClass)
IF InstantiatedObject.SubClass1 IS NOTHING THEN

That's trying to get at SubClass1 as if it were a property, not a
nested type. They're not the same thing at all.

Now, your MyClass type might *also* have a property of type SubClass1,
but it's not clear that it does...
 
P

Peter Duniho

This pseudocode hopefully makes it more understandable in what I am
attempting it to do.

IMHO, you first need to know yourself what it is you're trying to do.
The classes/subclasses:

Public Class MyClass
Public Class SubClass1
End Class

Public Class SubClass2
Public Class SubSubClass1
End Class
End Class

Public Class SubClass3
End Class
End Class

Terminology is very important. In spite of the names you've given them,
"SubClass1", "SubClass2", and "SubClass3" are not sub-classes of "MyClass".

It's confusing when you misuse the terms, and frankly it is probably most
confusing to _you_, because it prevents you from being able to find the
relevant information on MSDN or other sources. It also prevents you from
understanding whether what you're trying to do is legal or not.

In particular, if I understand your code sample correctly, you are under
the impression that if you have an instance of "MyClass", that there are
members corresponding to the individual nested classes. This is not the
case at all. So the code you wrote here:
The "code":
Public Sub InstantiateAllObjects(ByRef InstantiatedObject AS MyClass)
IF InstantiatedObject.SubClass1 IS NOTHING THEN
InstantiatedObject.SubClass1 = NEW MyClass.SubClass1
IF InstantiatedObject.SubClass2 IS NOTHING THEN
InstantiatedObject.SubClass2 = NEW MyClass.SubClass2
IF InstantiatedObject.SubClass2.SubSubClass1 IS NOTHING THEN
InstantiatedObject.SubClass2.SubSubClass1 = NEW
MyClass.SubClass2.SubSubClass1
IF InstantiatedObject.SubClass3 IS NOTHING THEN
InstantiatedObject.SubClass3 = NEW MyClass.SubClass3
End Sub

....doesn't make any sense. There's no such things as
"InstantiatedObject.SubClass1", "InstantiatedObject.SubClass2", and
"InstantiatedObject.SubClass1" (never mind the class nested two levels
deep, "SubSubClass1").

If an instance of "MyClass" needs an instance of a nested class, then it
should create them itself. It is not generally useful to just go creating
instances of nested classes contained within a given class. That's not
why nested classes exist. IMHO, it's a sign of a design problem if you
think you do need to do this.

Now, all that said...as far as your specific goal goes, if you really
insist on doing this sort of thing, you may want to look at the
Type.GetNestedTypes() method. Given an instance of a particular Type
(e.g. "MyClass"), it will return a collection of the nested types within
that class (e.g. "SubClass1", "SubClass2", and "SubClass3"). Of course,
you need a place to put those instances. A class doesn't by default have
any members that store references to nested classes, so you'd need to
create those members yourself.

It's difficult to understand why it is you are trying to do this. If you
can briefly explain in more detail what led you to this design, it may be
possible to offer advice as to how to fix the design so that you don't
need to do this.

One possible alternative you might consider, depending on what you're
trying to do, is to implement the singleton pattern for these classes
(e.g. http://en.wikipedia.org/wiki/Singleton_pattern).

Pete
 

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