Recasting object from a variable or type object.

G

Guest

I have a custom class that has been assigned to a variable and worked with, I
now need to cast this class as a different class, which is in a separate
assembly, not currently in the project. Normally if it was part of the
project I would say:

MyNewClass newClassObject = (MyNewClass) currentClassObject;

I have the name of the class, assembly and namespace in separate variables.
I even have a variable of ‘Type’ that is equal to ‘MyNewClass’ (from below
code)

string stuffToLoad = myNameSpace + "." + myClass + ", " + myAssembly;
Type myType = Type.GetType(stuffToLoad, true);

My problem is that I need to recast currentClassObject into MyNewClass and
I seem to have run out of options. Have tried several roads already. Anyone
have any ideas?

-phil
 
J

Jianwei Sun

I just don't understand, if you have a reference to the assembly, you
should be able to do something the same as if the case is valid :
MyNewClass newClassObject = (MyNewClass) currentClassObject;

Maybe I miss your point.

Jianwei
 
G

Guest

Jianwei Sun said:
I just don't understand, if you have a reference to the assembly, you
should be able to do something the same as if the case is valid :

Perhaps that is my problem, that it is too simple <w>. I’ve only been
working in C# for about six months so it is still new to me.

// Set Assembly Filename
string assemblyFileName = String.Concat(GetAppPath(), myAssembly, ".dll");
// Create Assembly
Assembly a = Assembly.LoadFrom(assemblyFileName);

MyNewClass newClassObject = (MyNewClass) currentClassObject;

---

Using the above reference to the proper assembly how do I recast as above?
I tried:

typeof(a.gettype(myClass) newClassObject = (typeof(a.gettype(myClass))
currentClassObject;

and several other variations…
 
J

Jon Skeet [C# MVP]

Phil said:
I have a custom class that has been assigned to a variable and worked with, I
now need to cast this class as a different class, which is in a separate
assembly, not currently in the project. Normally if it was part of the
project I would say:

MyNewClass newClassObject = (MyNewClass) currentClassObject;

I have the name of the class, assembly and namespace in separate variables.
I even have a variable of ?Type? that is equal to ?MyNewClass? (from below
code)

string stuffToLoad = myNameSpace + "." + myClass + ", " + myAssembly;
Type myType = Type.GetType(stuffToLoad, true);

My problem is that I need to recast currentClassObject into MyNewClass and
I seem to have run out of options. Have tried several roads already. Anyone
have any ideas?

Well, why do you want to cast? Presumably it's to use a member of the
type - if you know the member at compile time, how come you don't know
the actual type? The usual answer here is that you know some interface
that the type implements, and you only need to call a member in that
interface - in which case, just cast to the interface.
 
G

Guest

Jon Skeet said:
Well, why do you want to cast? Presumably it's to use a member of the
type - if you know the member at compile time, how come you don't know
the actual type? The usual answer here is that you know some interface
that the type implements, and you only need to call a member in that
interface - in which case, just cast to the interface.

Yes, I use a factory to create instances of classes that are not in my
project. I use an interface to get at them, but the current interface does
not contain a reference to a variable I need. Therefore I would like to get
access to the derived class by recasting it.

I tried: Convert.ChangeType(currentObject, myNewType);

and this does correctly recast the object, however my code then has no idea
that I understand the object and fails when I try to use a method or variable
on it. That is:
currentObject.methodOfMyNewType; // This fails to compile

This seems to make me think that the method I'm try to accomplish here may
not bear fruit either. Seems like I need to make my code understand I really
do understand it.
 
J

Jon Skeet [C# MVP]

Phil said:
Yes, I use a factory to create instances of classes that are not in my
project. I use an interface to get at them, but the current interface does
not contain a reference to a variable I need. Therefore I would like to get
access to the derived class by recasting it.

I tried: Convert.ChangeType(currentObject, myNewType);

and this does correctly recast the object, however my code then has no idea
that I understand the object and fails when I try to use a method or variable
on it. That is:
currentObject.methodOfMyNewType; // This fails to compile

This seems to make me think that the method I'm try to accomplish here may
not bear fruit either. Seems like I need to make my code understand I really
do understand it.

I don't understand why you don't just cast to the actual type. If the
compiler has to know about the type anyway (in order to compile the
last line above), why can't it know about it to compile it?
 
G

Guest

I don't understand why you don't just cast to the actual type. If the
compiler has to know about the type anyway (in order to compile the
last line above), why can't it know about it to compile it?

The entire purpose I'm doing this is so that there is NO reference to the
assembly I'm trying to cast it to. That is why I use a Factory to create the
object in the first place. My question is simply, is there a way to do this:

NewClass myNewObject = (NewClass) myOldObject ;

where all I have is the previously mentioned info. It seems that:

Convert.ChangeType(currentObject, myType);

does the same thing, but when I try and use any methods of the myType class
since it does not have prior knowledge of its methods, it will not allow me
to compile.

-phil
 
G

Guest

Phil said:
The entire purpose I'm doing this is so that there is NO reference to the
assembly I'm trying to cast it to.

which is a pointless thing to do. because regardless whether you have a
hard reference at compile time or not, at runtime, that assembly will HAVE TO
be loaded if you want to execute any code in it.
That is why I use a Factory to create the
object in the first place.

If you are using a factory, then you should limit everything you access to
be defined in a common interface. otherwise the whole factory pattern is
kinda pointless.
My question is simply, is there a way to do this:

NewClass myNewObject = (NewClass) myOldObject ;

where all I have is the previously mentioned info.

there is no way to do dynamic cast at runtime because casting is a compile
time concept. to achieve what you want, you need to make late-bound calls
through reflection. however, I still find your requirement a bit strange.
maybe I'm missing something.
 
G

Guest

*** Here is one solution, note that this only allows use of a single field
and not exsposure of the object that was desired. The field I wanted was a
'SortedList' type. ***

Keep in mind that myObject started out as the concrete class, and was
converted to the derived class which has the unexposed fields. The converted
derived class is then scanned for the desired field and set according. Not
exactly desired effect but still it gave me the data I needed.

string stuffToLoad = myNameSpace + "." + myClass + ", " + myAssembly;
Type myType = Type.GetType(stuffToLoad, true);

Convert.ChangeType(myObject, myType);

// List the members of theClass
BindingFlags myBindingFlags = BindingFlags.Instance | BindingFlags.NonPublic;

Type type = myObject.GetType();
foreach (FieldInfo fieldInfo in type.GetFields (myBindingFlags))
{
string nam = fieldInfo.Name;
if (nam == "sections")
{
sourceSections = (SortedList) fieldInfo.GetValue(myObject);
}
}

-Phil Fischer
 
J

Jon Skeet [C# MVP]

Phil said:
*** Here is one solution, note that this only allows use of a single field
and not exsposure of the object that was desired. The field I wanted was a
'SortedList' type. ***

Keep in mind that myObject started out as the concrete class, and was
converted to the derived class which has the unexposed fields. The converted
derived class is then scanned for the desired field and set according. Not
exactly desired effect but still it gave me the data I needed.

You don't actually need to scan through all the fields - you can just
call GetField with the appropriate field name.

It would be far better to encapuslate the extra field (preferrably as a
property) in a another interface.

Do you *actually* need to change the type, by the way? Does the
originally created type not contain the field, or were you just trying
to cast?
 

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