ConstructorInfo

G

Guest

When creating a class using the Invoke method of the ConstructorInfo, this
returns and object. I am wondering how I can reclass this object type into
the specific class type. Since I only have the "text" name of the class to
begin with, how can I make an object reclassed into an object of the class
which is of the text name that I have.

Type[] parms = { typeof(System.Data.OleDb.OleDbDataReader) };

Type theTblType = Type.GetType("MyClassName");
ConstructorInfo methodCreate = theTblType.GetConstructor(parms);

object[] argumentItems = { dr };
object rec = methodCreate.Invoke(theTblType, argumentItems);

How do I reclass "rec" into a type of "MyClassName" with only the text
name of
the class?
Thanks in advance for your assistance!!!
 
H

Hans Kesting

When creating a class using the Invoke method of the ConstructorInfo,
this returns and object. I am wondering how I can reclass this object
type into the specific class type. Since I only have the "text" name
of the class to begin with, how can I make an object reclassed into an
object of the class which is of the text name that I have.

Type[] parms = { typeof(System.Data.OleDb.OleDbDataReader) };

Type theTblType = Type.GetType("MyClassName");
ConstructorInfo methodCreate = theTblType.GetConstructor(parms);
object[] argumentItems = { dr };
object rec = methodCreate.Invoke(theTblType, argumentItems);
How do I reclass "rec" into a type of "MyClassName" with only the
text
name of
the class?
Thanks in advance for your assistance!!!

Usually you will know something in advance about that dynamically
loaded class: a baseclass or an implemented interface.
Then you can cast that "rec" to the baseclass or interface and
work with the public methods and properties that are available
that way.

If you do know the name of a method to invoke, you could also
invoke that in a similar way to the code you already used to create the object.

Hans Kestin
 
I

Ignacio Machin \( .NET/ C# MVP \)

Hi,

OldButStillLearning said:
When creating a class using the Invoke method of the ConstructorInfo, this
returns and object. I am wondering how I can reclass this object type
into
the specific class type.

If you know the type of the instance you are creating then why are you using
reflection in the first place?
 
G

Guest

As stated, I have a "text" version of the type. The type could be one of
250+ values and these could change all of the time. So I am using reflection
to change the text name of the class into an instance of the class. Now when
I actually create the instance of the class, it is a type of "object" and I
need it to be a type of the "text name of the class".
 
G

Guest

I do know something about the class that I am creating. I know the method
that I want to invoke, but that is not my question.

I have a method which requires an instance of an object. The instance that
is required is the object which I just created via the
ConstructorInfo.Invoke(). So since the ConstructorInfo.Invoke() returns an
"object", how can I change it from "object" to the class type for which I
have the text name for the class?

I hope this explains it better...
 
J

Jon Skeet [C# MVP]

OldButStillLearning said:
I do know something about the class that I am creating. I know the method
that I want to invoke, but that is not my question.

I have a method which requires an instance of an object. The instance that
is required is the object which I just created via the
ConstructorInfo.Invoke(). So since the ConstructorInfo.Invoke() returns an
"object", how can I change it from "object" to the class type for which I
have the text name for the class?

I hope this explains it better...

Your method is presumably declared to return object anyway - you don't
need a cast, as that's a compile-time measure.

Just return the result of ConstructorInfo.Invoke.
 
G

Guest

Thanks Jon...

But, I'm not clear. Are you saying that if I have a method which requires
an instance of "MyClass" as an input parameter, that I can instead pass a
"cast" of my "MyClass" as a type of "object"?

I don't think I can do this. Doesn't the compiler require the type of my
object to be "MyClass" and won't it complain if I attempt to pass it a type
of "object"?

So I am trying to figure out, now that I have a type of "object" for the
class which was created via the ConstructorInfo.Invoke() method, how I can
reclass the object to "MyClass" when I only have the "text" name of the class?
 
I

Ignacio Machin \( .NET/ C# MVP \)

Hi,

OldButStillLearning said:
As stated, I have a "text" version of the type. The type could be one of
250+ values and these could change all of the time. So I am using
reflection
to change the text name of the class into an instance of the class. Now
when
I actually create the instance of the class, it is a type of "object" and
I
need it to be a type of the "text name of the class".

That is not correct, the isntance is of the type of the "text name of the
class"; it's just that is being referenced by an object reference.
But you can invoke any member (method/properties) by using reflection.

If those 250+ types all implement a common interface you can cast the object
reference to it.
 
J

Jon Skeet [C# MVP]

OldButStillLearning said:
But, I'm not clear. Are you saying that if I have a method which requires
an instance of "MyClass" as an input parameter, that I can instead pass a
"cast" of my "MyClass" as a type of "object"?

If you know you're calling a method which requires a MyClass parameter,
then you must know that at compile time, and can therefore cast.
I don't think I can do this. Doesn't the compiler require the type of my
object to be "MyClass" and won't it complain if I attempt to pass it a type
of "object"?

So I am trying to figure out, now that I have a type of "object" for the
class which was created via the ConstructorInfo.Invoke() method, how I can
reclass the object to "MyClass" when I only have the "text" name of the class?

It's not clear *exactly* what your situation is.

Could you post a short but complete program which demonstrates the
problem?

See http://www.pobox.com/~skeet/csharp/complete.html for details of
what I mean by that.
 
G

Guest

I posted code in my original note, but perhaps it was not too clear, so Let
me try again... Here is the code

Type[] parms = { typeof(System.Data.OleDb.OleDbDataReader) };

Type theTblType = Type.GetType("MyClassName");
ConstructorInfo methodCreate = theTblType.GetConstructor(parms);

object[] argumentItems = { dr };
object rec = methodCreate.Invoke(theTblType, argumentItems);

"rec" (above) is an object created via the ConstructorInfo.Invoke, which
returns an object. It really is an instance of "MyClassName", but because
ConstructorInfo.Invoke returns an object and does not cast to to the desired
object.

Now suppose I have another class which I have created via a text name, we
will call that class "MySecondClass". Again, all I know about this class is
its' text name. This has a method, let's call it "InsertRecord" and one of
the arguments for that method is an instance of "MyClassName", which in this
case is "rec" above, except that it is cast as an object. So how do I pass
"rec" as an arguement for the method "InsertRecord", when all I have is an
"object" which needs to be cast as "MyClassName".
 
J

Jon Skeet [C# MVP]

OldButStillLearning said:
I posted code in my original note, but perhaps it was not too clear, so Let
me try again... Here is the code

You posted a *snippet* of code in your original post. You've done the
same again.

The idea was to get a more *complete* picture of what you're trying to
do.
Type[] parms = { typeof(System.Data.OleDb.OleDbDataReader) };

Type theTblType = Type.GetType("MyClassName");
ConstructorInfo methodCreate = theTblType.GetConstructor(parms);

object[] argumentItems = { dr };
object rec = methodCreate.Invoke(theTblType, argumentItems);

"rec" (above) is an object created via the ConstructorInfo.Invoke, which
returns an object. It really is an instance of "MyClassName", but because
ConstructorInfo.Invoke returns an object and does not cast to to the desired
object.

Now suppose I have another class which I have created via a text name, we
will call that class "MySecondClass". Again, all I know about this class is
its' text name. This has a method, let's call it "InsertRecord" and one of
the arguments for that method is an instance of "MyClassName", which in this
case is "rec" above, except that it is cast as an object. So how do I pass
"rec" as an arguement for the method "InsertRecord", when all I have is an
"object" which needs to be cast as "MyClassName".

This is where by not showing the code, we're left guessing. Are you
trying to call the method by reflection? Or is it part of an interface?
 
B

Bram

Hello,

The short answer is: You can't. Since the text name of the class is
only known at runtime and you determine the casting operators at
compile-time there is no way the compiler can know in advance to what
type you object should be cast.

If you *do* know the type at compile time, the code would be as
follows:

Type[] parms = { typeof(System.Data.OleDb.OleDbDataReader) };

Type theTblType = typeof(MyClassName);
ConstructorInfo methodCreate = theTblType.GetConstructor(parms);

object[] argumentItems = { dr };
object rec = methodCreate.Invoke(theTblType, argumentItems);

MyClassName cast = (MyClassName)rec;

However, it looks like you are trying to accomplish a plugin type of
thing and fortunately there is a way to accomplish that. Let's say you
have a number of plugins that can generate a welcome string using the
datareader (yeah, it's lame but it works). The code should look as
follows:

public abstract class BasePlugin {
public BasePlugin(IDataReader reader) { // Why tie yourself to
OleDB?
// (..)
}

public abstract string GenerateWelcome();
}

public abstract class Plugin1 : Plugin {
public override string GenerateWelcome() {
return "Welcome world"; // You could also use the data reader but
this is shorter
}
}

public abstract class Plugin2 : Plugin {
// (code omitted)
}

Now you have several plugins, which could even reside in several
different assemblies. The code actually using the plugin would look
like this:

Type[] parms = { typeof(System.Data.OleDb.OleDbDataReader) };

Type theTblType = Type.GetType("Plugin1");
ConstructorInfo methodCreate = theTblType.GetConstructor(parms);

object[] argumentItems = { dr };
object rec = methodCreate.Invoke(theTblType, argumentItems);

Plugin plugin = (Plugin)rec;
Console.WriteLine(plugin.GenerateWelcome());

Note there is no compile-time checking of the type you supply to the
type.gettype() method. Instead of "Plugin1", you could also pass the
name of a type which is not a subclass of Plugin. This would generate
an exception when trying to instantiate the type (or when trying to
cast to plugin, if the type happens to have a constructor taking an
IDataReader).

Regards,
Bram
When creating a class using the Invoke method of the ConstructorInfo, this
returns and object. I am wondering how I can reclass this object type into
the specific class type. Since I only have the "text" name of the class to
begin with, how can I make an object reclassed into an object of the class
which is of the text name that I have.

Type[] parms = { typeof(System.Data.OleDb.OleDbDataReader) };

Type theTblType = Type.GetType("MyClassName");
ConstructorInfo methodCreate = theTblType.GetConstructor(parms);

object[] argumentItems = { dr };
object rec = methodCreate.Invoke(theTblType, argumentItems);

How do I reclass "rec" into a type of "MyClassName" with only the text
name of
the class?
Thanks in advance for your assistance!!!
 
K

Kalpesh

Hi,

As far as I understand - unless you refer the assembly at the compile
time, you cannot cast "rec" to "MyClassName".
Why would you want to do that?

If MyClass derives from an interface (e.g. Comparable), you could
write code as below
Comparable c = theTblType as Comparable

This way you could invoke methods on theTblType , since it is also
"Comparable".
I would appreciate if an expert will explain this in more simple
terms.

Thanks
Kalpesh
 

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