Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Can an object cast itself to a derived class?

Can an object cast itself to a derived class?

Scheduled Pinned Locked Moved C#
csharpc++designquestionlearning
4 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • T Offline
    T Offline
    Togakangaroo
    wrote on last edited by
    #1

    This is 50% curiousity, 50% because I might want to do this (so if this is a 'DON'T DO THIS EVER' type thing, by all means tell me) but I don't even know if its possible. Say you had something like this: class Book; class CheckedOutBook : Book; class Library ..void CheckOut(ref Book b, Person p); Is it possible for CheckOut() to transform the book input into it so it is now a CheckedOutBook? Obviously, you can return a new instance of CheckedOutBook, but I'm specifically talking about transforming the reference - my memories of C++ are that with pointers it should certainly be possible, but is it in C#? To be clear I'm thinking of something like this: Book b = new Book("Design Patterns"); (new Library()).CheckOut(b, new Person("Frank")); Diagnostics.Assert(b is Book); Diagnostics.Assert(b is CheckedOutBook);

    C C 2 Replies Last reply
    0
    • T Togakangaroo

      This is 50% curiousity, 50% because I might want to do this (so if this is a 'DON'T DO THIS EVER' type thing, by all means tell me) but I don't even know if its possible. Say you had something like this: class Book; class CheckedOutBook : Book; class Library ..void CheckOut(ref Book b, Person p); Is it possible for CheckOut() to transform the book input into it so it is now a CheckedOutBook? Obviously, you can return a new instance of CheckedOutBook, but I'm specifically talking about transforming the reference - my memories of C++ are that with pointers it should certainly be possible, but is it in C#? To be clear I'm thinking of something like this: Book b = new Book("Design Patterns"); (new Library()).CheckOut(b, new Person("Frank")); Diagnostics.Assert(b is Book); Diagnostics.Assert(b is CheckedOutBook);

      C Offline
      C Offline
      Colin Angus Mackay
      wrote on last edited by
      #2

      Togakangaroo wrote:

      This is 50% curiousity, 50% because I might want to do this (so if this is a 'DON'T DO THIS EVER' type thing, by all means tell me) but I don't even know if its possible.

      Code in the base class can cast itself to a derived class IF (AND ONLY IF) the object is actually an instance of the derived class in the first place. HOWEVER, (and you're way ahead of me), this is a "DON'T DO THIS EVER" type of thing. The base class should have no knowledge of its derived classes. It is the responsibility of the derived class to know about its base. If a base class uses information about derived classes then you lock the base class effectively. The base is no longer open to extension by other new derived classes at a later date. Any new derived class would potentially require changes in the base. This is bad.

      Togakangaroo wrote:

      Is it possible for CheckOut() to transform the book input into it so it is now a CheckedOutBook?

      This is a different question. CheckOut is a method on Library which is not in the same class heirarchy as Book and CheckedOutBook. You have a ref Book b in the method signature, so I suppose you could REPLACE b with a CheckedOutBook but not transform the existing one. Also I consider using ref and out to be poor practice. In an OO system there are many better ways to accomplish the same thing. I see that there is no return value for the method so there really is no reason at all to be using ref as you can do that through the return value. Also, the implication of CheckedOutBook is that you are assigning state (whether the book is checked out or not) to the class. State should be a property of the class, not the reason d'etre of the class. I hope this helps.

      Recent blog posts: *SQL Server / Visual Studio install order *Installing SQL Server 2005 on Vista *Crazy Extension Methods Redux * Mixins My Blog

      T 1 Reply Last reply
      0
      • C Colin Angus Mackay

        Togakangaroo wrote:

        This is 50% curiousity, 50% because I might want to do this (so if this is a 'DON'T DO THIS EVER' type thing, by all means tell me) but I don't even know if its possible.

        Code in the base class can cast itself to a derived class IF (AND ONLY IF) the object is actually an instance of the derived class in the first place. HOWEVER, (and you're way ahead of me), this is a "DON'T DO THIS EVER" type of thing. The base class should have no knowledge of its derived classes. It is the responsibility of the derived class to know about its base. If a base class uses information about derived classes then you lock the base class effectively. The base is no longer open to extension by other new derived classes at a later date. Any new derived class would potentially require changes in the base. This is bad.

        Togakangaroo wrote:

        Is it possible for CheckOut() to transform the book input into it so it is now a CheckedOutBook?

        This is a different question. CheckOut is a method on Library which is not in the same class heirarchy as Book and CheckedOutBook. You have a ref Book b in the method signature, so I suppose you could REPLACE b with a CheckedOutBook but not transform the existing one. Also I consider using ref and out to be poor practice. In an OO system there are many better ways to accomplish the same thing. I see that there is no return value for the method so there really is no reason at all to be using ref as you can do that through the return value. Also, the implication of CheckedOutBook is that you are assigning state (whether the book is checked out or not) to the class. State should be a property of the class, not the reason d'etre of the class. I hope this helps.

        Recent blog posts: *SQL Server / Visual Studio install order *Installing SQL Server 2005 on Vista *Crazy Extension Methods Redux * Mixins My Blog

        T Offline
        T Offline
        Togakangaroo
        wrote on last edited by
        #3

        Good point about not having a base class cast itself - As you pointed out, I guess in what I was saying CheckOut() would be what is doing the casting and really the only reason I would want to do this would be for fear of someone referring to the old variable later on in the scope. Obviously there are much better ways of preventing this. So let's move this entirely into the "I'm just curious" column.

        1 Reply Last reply
        0
        • T Togakangaroo

          This is 50% curiousity, 50% because I might want to do this (so if this is a 'DON'T DO THIS EVER' type thing, by all means tell me) but I don't even know if its possible. Say you had something like this: class Book; class CheckedOutBook : Book; class Library ..void CheckOut(ref Book b, Person p); Is it possible for CheckOut() to transform the book input into it so it is now a CheckedOutBook? Obviously, you can return a new instance of CheckedOutBook, but I'm specifically talking about transforming the reference - my memories of C++ are that with pointers it should certainly be possible, but is it in C#? To be clear I'm thinking of something like this: Book b = new Book("Design Patterns"); (new Library()).CheckOut(b, new Person("Frank")); Diagnostics.Assert(b is Book); Diagnostics.Assert(b is CheckedOutBook);

          C Offline
          C Offline
          chaiguy1337
          wrote on last edited by
          #4

          I agree with Colin for the most part. It seems as though you are looking to use the class itself as a way to represent some information about the instance. Although as you mentioned this can work in C++, C# works very differently, and the type of an object really represents two things: first of all, the actual type of the instance, and secondly (in the case of base classes) a common interface (since subclassing is really just a way of implementing the base class's interface, from the perspective of someone using the object). Anyhow, if you were to cast the instance of ref Book b to a CheckedOutBook inside CheckOut(), this would actually only apply to the local representation of b, and even though it's marked as ref, would not affect the object passed into it, namely because that object in the calling method already has an interpretation (type), and ref parameters allow an object to be changed, not how it is interpreted (i.e. its local apparent type). As far as it being a "DON'T DO THIS EVER" thing, I think you'll quickly realize that it won't work, so it's not so much a warning as there's just no point in doing it. Now that said, you might actually be able to do something like what you want by creating a new object of type CheckedOutBook, setting it as somehow equivalent to the passed-in Book, and then setting the ref b parameter to equal the new instance (since it is still a Book). The key is that you will have to create a new object, and the old one will still be floating around so long as it is used (elsewhere). However you appear to be aware of this scenario. The short answer is no, you cannot "transform" a reference to be some type other than how it was created. Not in C#.

          “Time and space can be a bitch.” –Gushie, Quantum Leap {o,o}.oO( Looking for a great RSS reader? Try FeedBeast! ) |)””’)            Built with home-grown CodeProject components! -”-”-

          1 Reply Last reply
          0
          Reply
          • Reply as topic
          Log in to reply
          • Oldest to Newest
          • Newest to Oldest
          • Most Votes


          • Login

          • Don't have an account? Register

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • World
          • Users
          • Groups