Casting a C# base class object to a derived class type.

G

Guest

Is there any way to cast a base class object to a derived class datatype when
the derived class adds no new fields nor alters the object allocation in any
way?

The scenario would be where you want to extend a base class by adding only
methods and properties, however, only base class objects are provided to you.

Here is a sample:

public class Base
{
protected int val = 0;
}

public class Derived : Base
{
public int GetVal()
{
return val;
}
}

Then using those classes in a function like this:

public int Fn( Base a )
{
Derived b = (Derived)a;
return b.GetVal();
}

Assuming allocation doesn't change, there should be no harm in doing a cast
like this. Are there class modifiers that could handle this?

Thanks, Chris.
 
J

John B

Chris said:
Is there any way to cast a base class object to a derived class datatype when
the derived class adds no new fields nor alters the object allocation in any
way?

The scenario would be where you want to extend a base class by adding only
methods and properties, however, only base class objects are provided to you.

Here is a sample:

public class Base
{
protected int val = 0;
}

public class Derived : Base
{
public int GetVal()
{
return val;
}
}

Then using those classes in a function like this:

public int Fn( Base a )
{
Derived b = (Derived)a;
return b.GetVal();
}

This would work fine unless a is not of type Derived, in which case you
would get an invalidcastexception.

Assuming allocation doesn't change, there should be no harm in doing a cast
like this. Are there class modifiers that could handle this?
What do you mean?
Thanks, Chris.

Have you tried this out?

JB
 
C

Chris Dunaway

You can only cast it if a is actually an instance of Derived. You
should use the is keyword:

public int Fn( Base a )
{
if (a is Derived)
{
Derived b = (Derived)a;
return b.GetVal();
}
else
\\Do something else here;
}
 
G

Guest

Sorry. I may not have been clear in my original post. Perhaps the example
function should have been more like:

Base a = new Base();
Derived b = (Derived)a; //*** this will fail as an invalid cast
b.GetVal();

The above code casts an error because "a" has been created as a Base object,
not a Derived object. Attempting to cast "a" to the wrong type of object
causes an exception. But...

If the Derived class were to only add methods and properties, there should
be no harm in making this cast. For all intensive purposes, a Derived object
would look identical to a Base object in memory.

To give you a real world example, take the XmlElement object for instance.
It is created by calling XmlDocument.CreateElement(). Since an XmlElement
can't be created on its own, there is no way to extend this class with new
functionality. All you can do is wrapper a reference to it within another
class.

Suppose though, there were a class modifier which said, "this derived class
does not modify the base object so the two can be used interchangeably". You
could then extend base objects without knowing anything about how they were
created.

Cha', Chris.
 
J

Jon Skeet [C# MVP]

Chris Capon said:
Sorry. I may not have been clear in my original post. Perhaps the example
function should have been more like:

Base a = new Base();
Derived b = (Derived)a; //*** this will fail as an invalid cast
b.GetVal();

The above code casts an error because "a" has been created as a Base object,
not a Derived object. Attempting to cast "a" to the wrong type of object
causes an exception. But...

If the Derived class were to only add methods and properties, there should
be no harm in making this cast. For all intensive purposes, a Derived object
would look identical to a Base object in memory.

That doesn't mean it would be harmless though. It would behave
differently. If I pass you a reference to an instance of a base class,
I don't want you to be able to treat it as if it were an instance of a
derived class which might have radically different behaviour.
To give you a real world example, take the XmlElement object for instance.
It is created by calling XmlDocument.CreateElement(). Since an XmlElement
can't be created on its own, there is no way to extend this class with new
functionality. All you can do is wrapper a reference to it within another
class.
Yup.

Suppose though, there were a class modifier which said, "this derived class
does not modify the base object so the two can be used interchangeably". You
could then extend base objects without knowing anything about how they were
created.

Well, I'm afraid you can't. Personally I've rarely found I've wanted to
do this, but I'm glad I can't from a security point of view. Treating
an object as if it were an instance of a different type sounds pretty
dangerous to me.
 
G

Guest

:

Well, I'm afraid you can't. Personally I've rarely found I've wanted to
do this, but I'm glad I can't from a security point of view. Treating
an object as if it were an instance of a different type sounds pretty
dangerous to me.

Cool. Thanks anyway.
 

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