Tags: adds, allocation, alters, base, cast, casting, class, datatype, derived, fields, net, nor, object, sharp, type, whenthe

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

On .Net » .Net C# (C sharp)

6,216 words with 5 Comments; publish: Mon, 31 Dec 2007 14:21:00 GMT; (100109.38, « »)

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.

All Comments

Leave a comment...

  • 5 Comments
    • Chris Capon wrote:

      > 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

      #1; Mon, 31 Dec 2007 14:22:00 GMT
    • 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;

      }

      #2; Mon, 31 Dec 2007 14:23:00 GMT
    • 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.

      #3; Mon, 31 Dec 2007 14:24:00 GMT
    • Chris Capon <ChrisCapon.net-csharp.todaysummary.com.discussions.microsoft.com> wrote:

      > 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.

      --

      Jon Skeet - <skeet.net-csharp.todaysummary.com.pobox.com>

      http://www.pobox.com/~skeet

      If replying to the group, please do not mail me too

      #4; Mon, 31 Dec 2007 14:25:00 GMT
    • "Jon Skeet [C# MVP]" wrote:

      > > 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.

      Cool. Thanks anyway.

      #5; Mon, 31 Dec 2007 14:26:00 GMT