Results 1 to 13 of 13

Thread: [RESOLVED] How can I access methods in a parent class?

  1. #1

    Thread Starter
    Junior Member
    Join Date
    Sep 2016
    Posts
    21

    Resolved [RESOLVED] How can I access methods in a parent class?

    I have two custom classes that we can call "Person" and "Line".

    "Line" inherits List(of T) and is basically a List(of Person), with some extra properties and methods.

    "Person" has a "Shirt" property that stores the color of their shirt.

    Suppose I have a method in "Line" called RedShirt that returns the index of a "Person" that is wearing a red shirt.

    How can I access the RedShirt function from a "Person" instance to locate the guy with the red shirt on?


    I have already passed a reference to the "Line" instance in the constructor for "Person" and can easily access it this way.
    However, because "Line" is a LIST(of Person), I run into trouble when I use serialization and de-serialization to make a deep copy of a "Person" object. I believe each copied "Person" has a reference to the parent "Line" which has references to all the "Person" objects which all reference the "Line" etc.

    I am persisting the "Line" to a disk file.
    I noticed if I add a New "Person" to the "Line", the file size grows slightly. If I a deep copy a "Person" and add it to the "Line", the file size doubles.

    So assuming the serialization deep copy operation in conjunction with the reference to parent list is what is causing my issue, How else might I reference the "Line" methods from a "Person" object to get information on other "Person" objects in the "Line"?

    I hope my analogy makes the question easier to understand rather than harder.

  2. #2
    Smooth Moperator techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,531

    Re: How can I access methods in a parent class?

    I have two custom classes that we can call "Person" and "Line".

    "Line" inherits List(of T) and is basically a List(of Person), with some extra properties and methods.

    "Person" has a "Shirt" property that stores the color of their shirt.

    Suppose I have a method in "Line" called RedShirt that returns the index of a "Person" that is wearing a red shirt.
    You were fine up to that point.

    How can I access the RedShirt function from a "Person" instance to locate the guy with the red shirt on?
    Owch! You don't. the Person class doesn't care. Line does. Line should iterate through the list, looking for where Person.Shirt = RedShirt, and then returns the index where that is found. Person shouldn't be doing the looking. Person doesn't care.

    I have already passed a reference to the "Line" instance in the constructor for "Person" and can easily access it this way.
    However, because "Line" is a LIST(of Person), I run into trouble when I use serialization and de-serialization to make a deep copy of a "Person" object. I believe each copied "Person" has a reference to the parent "Line" which has references to all the "Person" objects which all reference the "Line" etc.

    I am persisting the "Line" to a disk file.
    I noticed if I add a New "Person" to the "Line", the file size grows slightly. If I a deep copy a "Person" and add it to the "Line", the file size doubles.

    So assuming the serialization deep copy operation in conjunction with the reference to parent list is what is causing my issue, How else might I reference the "Line" methods from a "Person" object to get information on other "Person" objects in the "Line"?

    I hope my analogy makes the question easier to understand rather than harder.
    Ung... this is a different issue... but also points out a major flaw - why is the Line being passed into the constructor for Person? There's no need for that... and is probably why your serializations are so large... it's a recursion issue ... line contains a person, which contains a line, which has a person, which has a line... unless you're MC Escher, there's no need for that. A person is a person. A line is a line... a line should contain people, people shouldn't contain lines (unless you're an actor in Hollywood, in which case you would do lines, but again, that's another problem all together.)


    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  3. #3
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    38,988

    Re: How can I access methods in a parent class?

    I agree. Though it hasn't been explained in great detail (I have no idea what a Line really represents, though a Person will probably represent...a person), it has been explained in sufficient detail to make me feel that there is some confusion in the design. The whole bit about the deep copy made me suspicious. There may be uses for deep copies, and serialization/deserialization is a way to get there, but it may be a way that is too easy. It may be allowing you to make a deep copy when you really only want an intermediate copy. If the Person holds a reference to the Line that the Person is in (which seems wrong, but there are some places where it is right), then why would a clone of a Person not want to hold a reference to the same Line? If it does, then a deep copy using serialize/deserialize is too deep. Writing your own Clone method, while it takes a bit more code in many cases, would do what you want more effectively.
    My usual boring signature: Nothing

  4. #4

    Thread Starter
    Junior Member
    Join Date
    Sep 2016
    Posts
    21

    Re: How can I access methods in a parent class?

    Quote Originally Posted by techgnome View Post
    Owch! You don't. the Person class doesn't care. Line does. Line should iterate through the list, looking for where Person.Shirt = RedShirt, and then returns the index where that is found. Person shouldn't be doing the looking. Person doesn't care.
    -tg
    The person does care because it needs to know the location of another person. If the person in the red shirt is fifth in line, a user operation can tell another person (Person X) that red shirt is fifth in line and passes a unique ID of red shirt to Person X . Person X then stores an ID of the red shirt person. Say someone in front of red shirt gets out of line. Red shirt is now fourth in line. How can Person X get the position of the red shirt person based on the stored ID? The line has that information because it can search each person to see who has that ID.

    I never intended to have a copy of the entire line in each person. I just wanted a reference to it so I can run a method on the line that returns the red shirt position based on an ID. In the same way a radio button can get a reference to it's parent container to get information about other radio buttons in the parent container. The copy of the entire line was an unfortunate side effect of the serialization deep copy.

    If it helps, my person class is actually a complicated automation process step with lots of properties. And, my line is the sequence of all of the steps that make up the entire process. Normally the process flows from one step to another but in some cases, decision are made and the process must jump backward or forward to a different step. When editing a particular process step, the user can enter a step number to jump to. Because steps may be added and deleted, I don't store the "jump to" step's position in line (because it will change if steps are moved, added, or deleted). instead I store the unique ID of the "jump to" step in the step being edited. Then when it is time to jump, the sequence (line) searches the steps to find the one with the unique number and jumps there. Sometimes, though, the step itself needs to get the actual "jump to" step position based on it's stored unique ID. If the step has a reference to the sequence, it can just run the same method that the sequence uses when it needs to find that information.

  5. #5
    Smooth Moperator techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,531

    Re: How can I access methods in a parent class?

    If it helps, my person class is actually a complicated automation process step with lots of properties. And, my line is the sequence of all of the steps that make up the entire process. Normally the process flows from one step to another but in some cases, decision are made and the process must jump backward or forward to a different step.
    Then the process should raise an event to the line that says "Move back one step" ... or "Move on to the next step" ... bascially the process says "I'm done" and passes some info, and the line controller decides what happens... not the process.

    Think about a line of cars at a toll booth... yes, you may care that you're in a line... and you may care that you're fifth, but that doesn't affect what you're doing - waiting in line. When it's your turn to pay, the guy in front of you doesn't shout out the window "You're next!" does he? no... nor do you do the same to the person behind you.

    Instead what happens is when it's your turn, you pull up, the controller (toll booth) invokes the payment method... you respond by either completing the process and paying the correct amount, or you throw an exception ("Insufficient change") ... if the process is successful, the controller releases your process by raising the gate... and everyone in the queue moves on up.

    Because steps may be added and deleted, I don't store the "jump to" step's position in line (because it will change if steps are moved, added, or deleted). instead I store the unique ID of the "jump to" step in the step being edited.
    That's good and sound ...

    so when you need to jump to another step (either forward or back, or in any direction) ... I'd simply raise a JumpToStep event, the event args would include the StepID ... the list then goes, OK, I need to find this step, and it goes through that process and when it finds it, it invokes it. As I think about it, I'd have a List(Of Steps) and then a Disctionary(Of GUID, Integer) -- this assumes StepID is a guid ... the list contains the steps, in order... the Dictionary would contain the StepIDs as keys, and then the value would be the index of the step in the list... actually... I might just go straight for Dictionary(Of Guid, Step) ... other wise it could get messy trying to keep synching indexes during edits.

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  6. #6

    Thread Starter
    Junior Member
    Join Date
    Sep 2016
    Posts
    21

    Re: How can I access methods in a parent class?

    I am using the "line" to sequence the steps. But, I still need the step to know the actual step number based on the ID because the step class has a documentation feature (a method like "ToSring") that generates verbiage describing all of the operations in the step, including if certain conditions in that step cause a jump to another step.

  7. #7

    Thread Starter
    Junior Member
    Join Date
    Sep 2016
    Posts
    21

    Re: How can I access methods in a parent class?

    Quote Originally Posted by techgnome View Post
    Think about a line of cars at a toll booth... yes, you may care that you're in a line... and you may care that you're fifth, but that doesn't affect what you're doing - waiting in line. When it's your turn to pay, the guy in front of you doesn't shout out the window "You're next!" does he? no... nor do you do the same to the person behind you.

    -tg
    In your analogy, what if the driver needs to know whether he is in the EZPass lane or a "cash only' lane?


    (Sorry if this posts twice. I didn't see it post and assumed I did something wrong)

  8. #8
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    38,988

    Re: How can I access methods in a parent class?

    Still can be done with events, though holding a reference to the Line may be more efficient. Another alternative is that the Line could pass a delegate (essentially a pointer to a function in the Line class) to the constructor of the Person such that the Person could call that delegate to get certain information.

    To the greatest extent possible, a Line shouldn't know about a Person, and a Person shouldn't know about a Line. Trouble always arises once you entangle the functionality of two classes such that class A is dependent on the very existence of a class B that is external to A. The event model allows you to have A broadcast "Here's what I need." and, as long as somebody is listening for such a call, they can supply the answer. As long as there is somebody listening, all will be well and the two are not entangled.

    On the other hand, there is a bit of overhead to that solution. It's pretty minor, but it isn't zero. Holding a reference is another alternative, but serialization/deserialization isn't a good way to make any clones if that's what you're doing. Furthermore, if you hold a reference to one class in a different class, there is always a temptation to let the responsibilities of one bleed into the other, which will always create problems large and small. In this case, it sure seems like a Person is doing more than it should be doing. Like TG, I don't like the idea of the Person knowing information about other points in the list. However, there IS the doubly-linked list, where each object holds a reference to the next and last objects in the list, but those are just properties used by an external process for iterating the list. It only gets ugly if the element itself makes use of those references to change its own state.
    My usual boring signature: Nothing

  9. #9
    Smooth Moperator techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,531

    Re: How can I access methods in a parent class?

    Quote Originally Posted by tigerWereWolfMonkey View Post
    In your analogy, what if the driver needs to know whether he is in the EZPass lane or a "cash only' lane?


    (Sorry if this posts twice. I didn't see it post and assumed I did something wrong)
    you make a request for a line... and the controller tells you which line to be added to... but you still don't go stuffing the line and the other cars into your trunk... because once you're in a line, you don't care if it's ezpass or cash only... that's a decision that's made at the time you .Add yourself to the process. This is why it's suggested that List(of) are private and read-only... your controller then can make the decision which lane to put you in.

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  10. #10

    Thread Starter
    Junior Member
    Join Date
    Sep 2016
    Posts
    21

    Re: How can I access methods in a parent class?

    Thanks for the input.

    I resolved my situation which resulted from the serialization deep copy causing the person class to store the entire line instead of just a reference to it. I did this by replacing the line reference after the de-serialization so that it again only held the reference.

    This works for me. As I said, I am only using the reference to the line so a person can document itself in the one case where it needs to resolve the reference to another person. In all other cases the line is in control.

    I would be happy to continue this conversation to understand things better as you guys both hold the opinion that a child object shouldn't or doesn't need to know about it's parent. I again refer to the "parent" property of a control that allows it to refer to it's container. It seems to be very useful that for instance, a check box, when clicked can access and change the backcolor property of the container it is in/

  11. #11
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    38,988

    Re: [RESOLVED] How can I access methods in a parent class?

    To be clear, the deep copy DID copy the reference. Serialization was not created for copying, it was created for storing maps of classes. A class that holds a reference to another class is exactly what it was all about. The whole thing gets serialized when you serialize the outer class such that you can save the state of the whole thing and restore the state of the whole thing. What good would serialization be if all it did was store the utterly useless value that the reference variable holds? Once it was restored, that would be a reference to nothing predictable, which would be useless or worse.

    Remember, a reference type variable (ALL variables of any class type) doesn't hold the object. All the variable holds is a reference to the object, which exists somewhere out in memory. So, it's not holding the object, it's holding what amounts to the address of the memory where the object actually exists.

    So, here's what you are doing with your new version of the deep copy:

    1) Serialize to bytes the Person object and the Line object that the Person object has a reference to. Since that Line object also contains references to Person objects...those are getting serialized as well.

    2) Deserialize the whole mess, which means that a new Person object is created in memory, along with a new Line object and any other Person objects. You then replace the address of that new Line object with the address of the one you have, which means that the newly created one is unreachable, so it will eventually be cleaned up when the Garbage Collector runs...which will happen more frequently due to all the wasted memory, but still may not be all that frequent (wasted memory is common in applications these days because memory is abundant and cheap).

    A better solution would be to not use Serialize/Deserialize to overcopy, but write a method in Person that returns a Person. I always name such methods Clone, though I'm not sure there's any rule on that. Inside the method, you do what copying needs to be done, which is generally not much. Sure, it might be a dozen lines, or so, but the savings are pretty great.
    My usual boring signature: Nothing

  12. #12

    Thread Starter
    Junior Member
    Join Date
    Sep 2016
    Posts
    21

    Re: [RESOLVED] How can I access methods in a parent class?

    Quote Originally Posted by Shaggy Hiker View Post
    A better solution would be to not use Serialize/Deserialize to overcopy, but write a method in Person that returns a Person. I always name such methods Clone, though I'm not sure there's any rule on that. Inside the method, you do what copying needs to be done, which is generally not much. Sure, it might be a dozen lines, or so, but the savings are pretty great.
    Thanks for the additional information. If it was only a dozen lines, I would have done exactly as you said to begin with. However, it is a very large class with a ton of properties. I found the serialization / de-serialization cloning method online and it was a quick shortcut. I did not have the knowledge or time to understand how it actually worked I just used it. I am all for doing things "the right way' so when I get other things worked out and have time to spend on it, i will switch to adding a Clone method in Person.

    Thanks again!

  13. #13
    PowerPoster
    Join Date
    Mar 2002
    Location
    UK
    Posts
    4,780

    Re: [RESOLVED] How can I access methods in a parent class?

    To note, you can mark a field as NonSerializable, to keep the reference to the Parent clean during your clone. You have to put it in after manually of course.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width