Dynamic casting at runtime

D

DaTurk

Hi,

This is a question brought about by a solution I came up with to
another question I had, which was "Dynamic object creation". So, I'm
curious if you can dynamically cast an object. If you have two object
which have a common base class, they can both be cast up to the base
class, but if either of the child classes have unuque methods you will
not be able to access them. Now I know about late binding and all that
stuff, but I need a much more light weight solution.

So I was hoping to have an instance of the base class, and cast it
between the children depending on what's decided during runtime. But
I'm not sure how to represent the class so it can be cast, and chaged.

I originally thought to have System.Type variables representing the two
child classes, and then a third System.Type which I would = to which
ever of the child types was chosen, and that third one could be the
"cast to" class variable, but I don't know how to represent the class
so the cast will work.

So like this,

System.Type childA = typeof(childA);
System.Type childB = typeof(childB);

System.Type generalChild = "which ever child the user wantes";

Parent parent = null;

//later in the program
((generalChild)parent)."the correct method for the child in
generalChild"

But I can't figure out how to represent a class in a way, form a type,
that the system will let this compile. THanks in advance for the help.
 
N

Nicholas Paldino [.NET/C# MVP]

There is no way to do this. Reflection is your only option in this
case.

Hope this helps.
 
G

Guest

DaTurk,
I believe your best approach here would be to look into having your objects
all implement the same interface. You can then create an instance of
IMyObject no matter what the actual class is, and call its interface - based
methods reliably.
Peter
 
D

DaTurk

Would it be possible for you to give me an exaple of how to do it? All
fo the examples I've found a very long winded, and not at all
practical. I might as well just create a seperate class.
There is no way to do this. Reflection is your only option in this
case.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

DaTurk said:
Hi,

This is a question brought about by a solution I came up with to
another question I had, which was "Dynamic object creation". So, I'm
curious if you can dynamically cast an object. If you have two object
which have a common base class, they can both be cast up to the base
class, but if either of the child classes have unuque methods you will
not be able to access them. Now I know about late binding and all that
stuff, but I need a much more light weight solution.

So I was hoping to have an instance of the base class, and cast it
between the children depending on what's decided during runtime. But
I'm not sure how to represent the class so it can be cast, and chaged.

I originally thought to have System.Type variables representing the two
child classes, and then a third System.Type which I would = to which
ever of the child types was chosen, and that third one could be the
"cast to" class variable, but I don't know how to represent the class
so the cast will work.

So like this,

System.Type childA = typeof(childA);
System.Type childB = typeof(childB);

System.Type generalChild = "which ever child the user wantes";

Parent parent = null;

//later in the program
((generalChild)parent)."the correct method for the child in
generalChild"

But I can't figure out how to represent a class in a way, form a type,
that the system will let this compile. THanks in advance for the help.
 
N

Nicholas Paldino [.NET/C# MVP]

DaTurk,

The examples that you have on late binding should show you what you need
to do.

The reason this doesn't work is that you are asking the compiler to
allow the cast to succeed, when in reality, it doesn't know what the type
will be until runtime. The compiler can't do that in good conscience.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

DaTurk said:
Would it be possible for you to give me an exaple of how to do it? All
fo the examples I've found a very long winded, and not at all
practical. I might as well just create a seperate class.
There is no way to do this. Reflection is your only option in this
case.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

DaTurk said:
Hi,

This is a question brought about by a solution I came up with to
another question I had, which was "Dynamic object creation". So, I'm
curious if you can dynamically cast an object. If you have two object
which have a common base class, they can both be cast up to the base
class, but if either of the child classes have unuque methods you will
not be able to access them. Now I know about late binding and all that
stuff, but I need a much more light weight solution.

So I was hoping to have an instance of the base class, and cast it
between the children depending on what's decided during runtime. But
I'm not sure how to represent the class so it can be cast, and chaged.

I originally thought to have System.Type variables representing the two
child classes, and then a third System.Type which I would = to which
ever of the child types was chosen, and that third one could be the
"cast to" class variable, but I don't know how to represent the class
so the cast will work.

So like this,

System.Type childA = typeof(childA);
System.Type childB = typeof(childB);

System.Type generalChild = "which ever child the user wantes";

Parent parent = null;

//later in the program
((generalChild)parent)."the correct method for the child in
generalChild"

But I can't figure out how to represent a class in a way, form a type,
that the system will let this compile. THanks in advance for the help.
 
D

DaTurk

See that's the problem, they all do implement the same interface, but
all of the implementing classes have their own methods which I'll need
access too. That's where the problem comes in.
 
D

DaTurk

Is there any way to have the compiler throw it's morals out the window
and have it listen to my casting suggestions?
DaTurk,

The examples that you have on late binding should show you what you need
to do.

The reason this doesn't work is that you are asking the compiler to
allow the cast to succeed, when in reality, it doesn't know what the type
will be until runtime. The compiler can't do that in good conscience.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

DaTurk said:
Would it be possible for you to give me an exaple of how to do it? All
fo the examples I've found a very long winded, and not at all
practical. I might as well just create a seperate class.
There is no way to do this. Reflection is your only option in this
case.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Hi,

This is a question brought about by a solution I came up with to
another question I had, which was "Dynamic object creation". So, I'm
curious if you can dynamically cast an object. If you have two object
which have a common base class, they can both be cast up to the base
class, but if either of the child classes have unuque methods you will
not be able to access them. Now I know about late binding and all that
stuff, but I need a much more light weight solution.

So I was hoping to have an instance of the base class, and cast it
between the children depending on what's decided during runtime. But
I'm not sure how to represent the class so it can be cast, and chaged.

I originally thought to have System.Type variables representing the two
child classes, and then a third System.Type which I would = to which
ever of the child types was chosen, and that third one could be the
"cast to" class variable, but I don't know how to represent the class
so the cast will work.

So like this,

System.Type childA = typeof(childA);
System.Type childB = typeof(childB);

System.Type generalChild = "which ever child the user wantes";

Parent parent = null;

//later in the program
((generalChild)parent)."the correct method for the child in
generalChild"

But I can't figure out how to represent a class in a way, form a type,
that the system will let this compile. THanks in advance for the help.
 
B

Bruce Wood

Peter said:
DaTurk,
I believe your best approach here would be to look into having your objects
all implement the same interface. You can then create an instance of
IMyObject no matter what the actual class is, and call its interface - based
methods reliably.
Peter

I agree with Peter, although I would add that you may end up with
several interfaces, depending upon combinations of capabilities that
you want to exploit in each class. For each set of related capabilities
(properties / events / methods), simply define an interface and have
the relevant class(es) implement the interface. Then, when you want to
call a method that needs to use certain capabilities, just define it as
taking an object that implements the appropriate interface:

public ClassA : BaseClass, ICapabilitiesA { ... }
public ClassB : BaseClass, ICapabilitiesB { ... }
public ClassC : BaseClass, ICapabilitiesA, ICapabilitiesB { ... }
etc.

then your method can say:

public void MyMethod(ICapabilitiesB bObject)
{
...
}
 
D

DaTurk

Yes, that would work, but not in my case. The class needs to hold a
reference to the object implementing the interface. The classes that
are implementing the interface are client/server connection classes
I've built to abstract away from AsynchMultiCast jazz under the hood.
So it's kind of set up like this

Gui -> ConnectionClass -> Client or server-> low level connection jazz.
//Where Each class is holding a reference to the next.

So the connection class HAS to know which interface it's dealing with,
and hold a reference to it as it will be bound by events and settings
delegates in the GUI through the connectionclass. I really just don't
want to have to build another connection class, since the only thing
that really is going to change is the interface it's holding
internally. That's why all of this.
 
N

Nicholas Paldino [.NET/C# MVP]

No, there isn't. In all reality, the compiler can't know what type you
are trying to cast to, and therefore can't enforce the calls that you are
trying to make.

You might want to consider using late bound calls in VB for this, and
have the runtime throw an exception if the member is not found.

However, C# does not offer this (with good reason).

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

DaTurk said:
Is there any way to have the compiler throw it's morals out the window
and have it listen to my casting suggestions?
DaTurk,

The examples that you have on late binding should show you what you
need
to do.

The reason this doesn't work is that you are asking the compiler to
allow the cast to succeed, when in reality, it doesn't know what the type
will be until runtime. The compiler can't do that in good conscience.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

DaTurk said:
Would it be possible for you to give me an exaple of how to do it? All
fo the examples I've found a very long winded, and not at all
practical. I might as well just create a seperate class.

Nicholas Paldino [.NET/C# MVP] wrote:
There is no way to do this. Reflection is your only option in this
case.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Hi,

This is a question brought about by a solution I came up with to
another question I had, which was "Dynamic object creation". So,
I'm
curious if you can dynamically cast an object. If you have two
object
which have a common base class, they can both be cast up to the base
class, but if either of the child classes have unuque methods you
will
not be able to access them. Now I know about late binding and all
that
stuff, but I need a much more light weight solution.

So I was hoping to have an instance of the base class, and cast it
between the children depending on what's decided during runtime.
But
I'm not sure how to represent the class so it can be cast, and
chaged.

I originally thought to have System.Type variables representing the
two
child classes, and then a third System.Type which I would = to which
ever of the child types was chosen, and that third one could be the
"cast to" class variable, but I don't know how to represent the
class
so the cast will work.

So like this,

System.Type childA = typeof(childA);
System.Type childB = typeof(childB);

System.Type generalChild = "which ever child the user wantes";

Parent parent = null;

//later in the program
((generalChild)parent)."the correct method for the child in
generalChild"

But I can't figure out how to represent a class in a way, form a
type,
that the system will let this compile. THanks in advance for the
help.
 
L

liko81

DaTurk said:
Hi,

This is a question brought about by a solution I came up with to
another question I had, which was "Dynamic object creation". So, I'm
curious if you can dynamically cast an object. If you have two object
which have a common base class, they can both be cast up to the base
class, but if either of the child classes have unuque methods you will
not be able to access them. Now I know about late binding and all that
stuff, but I need a much more light weight solution.

So I was hoping to have an instance of the base class, and cast it
between the children depending on what's decided during runtime. But
I'm not sure how to represent the class so it can be cast, and chaged.

To the best of my knowledge, you don't need to. Using the
Activator.CreateInstance() function, you retrieve an instance of type
Object; however, that Object knows what specific class it was created
from (thanks to the same metadata that allowed you to create it in the
first place). You really don't even need to cast it to the base class,
though it can help you understand what you've done later.

The caveat with this is that, having dynamically created it, you cannot
statically access members on this class unless you cast to a
non-abstract base class that at least "stubs" the member. So instead,
keep going with reflection.

Object newClass;
string className = 'myClass';
string methodName = 'myMethod';
string propertyName = 'myProperty';
string nameSpace = 'myClasses';
Assembly myAssembly;
ObjectHandler myObjHandler;
PropertyInfo _property;
MethodInfo _method;
Type myType;

//Get the assembly by calling GetExecutingAssembly() or LoadAssembly()
myAssembly = Assembly.GetExecutingAssembly();

myObjectHandler = Activator.CreateInstance(myAssembly.FullName,
nameSpace);
newClass = myObjectHandler.Unwrap();

//This is the code you need
myType = newClass.GetType() //this will return a myClass-instantiated
Type
_property = myType.GetProperty(propertyName); //gets property info
_property.SetValue(newClass, "value", null);

this should get no compile errors, and the system will do what it needs
to at runtime. No, it's not a static call, but it's far more readable
and maintainable than a switch statement for every object you'd expect
to create (read: every class derived from that base class). Besides,
casting a class to an "endpoint" derived class is required only if
you're going to place it in a variable of that type, which would have
to be statically declared.
 
D

DaTurk

Besides, casting a class to an "endpoint" derived class is required only if
you're going to place it in a variable of that type, which would have
to be statically declared.

The reason I want to cast it to the child is because I don't know of
any other way to access the child specific, methods. How would I do
that then?
 
L

liko81

DaTurk said:
The reason I want to cast it to the child is because I don't know of
any other way to access the child specific, methods. How would I do
that then?

You can use reflection, or you can call a method that is not abstract
on the base class that you cast to, and the application will know to
use the instance's implementation (this is more a hack than best
practices, and you will still get a compiler error if you try to call
an abstractly-defined member function).

There is another method you can use if you know at compile-time that
the class you will be dealing with is one of a small group (say you're
cataloguing vehicles, and know that the vehicle can only be a Car,
Truck, Van, SUV, Motorcycle, or RV). Call the object's GetType()
method, then compare what that returns to the results of the typeof()
operator when passed each class that this object could have been. This
allows for a specific cast, but it vastly reduces the maintainability
and utility of the code, as you are specifying limits on the types of
objects that can be used here, and you must change this code to
increase those limits. For instance, to add the ability to catalogue a
Boat, you must implement the Boat object AND change the casting code to
work with a Boat. I would only recommend this for small RAD projects
with a limited lifespan, since it saves code and the expandability is
not an issue.

I described using reflection above, but to summarize, you will call
your object's GetType() member (you don't need to have overridden it)
to obtain a Type object. You then call the GetMethod() method of the
Type object to get a MethodInfo object, and then you call
MethodInfo.Invoke() and pass it the class instance and parameters, and
it will return the method's return value if any. It'll look something
like this:

Object myObject; (instantiated as some derived class)
Type myObjectType;
MethodInfo myMethod;
Object returnValue;
object[] parameterArray;

myObjectType = myObject.GetType();
myMethod = myObjectType.GetMethod("MethodName");
//TODO: initialize parameterArray with all parameters to be passed, in
order
//TODO: set parameterArray to new Object[0] if method doesn't take any
parameters
returnValue = myMethod.Invoke(myObject, parameterArray);
 

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