Question How to identify one given instance from a class when debugging?

VBobCat

Well-known member
Joined
Sep 6, 2011
Messages
137
Location
S?o Paulo, Brazil
Programming Experience
3-5
Hello people,
I wrote a class that helps me to validate entries on textboxes and comboboxes.
The constructor takes the control to be validated as parameter, so the class can handle some of its events.
Then, each Form declares so many instances of it as the number of controls that require validation.
Since some controls' list of options depend on previous entries on other controls, the same methods on validating class are invoked in cascade, one time for each instance.
Is there a way for me to trace the stack of calls in order to identify to which particular instance belongs execution, when I freeze running in a step into one of these class methods?
Thank you very much.
 
Last edited:

jmcilhinney

VB.NET Forum Moderator
Staff member
Joined
Aug 17, 2004
Messages
14,295
Location
Sydney, Australia
Programming Experience
10+
As an example, I just tested this code:
Public Class Form1

    Private t1 As Thing

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim t2 As New Thing With {.Control = TextBox2}

        t1 = New Thing With {.Control = TextBox1, .Child = t2}
    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        t1.DoSomething()
    End Sub

End Class


Public Class Thing
    Public Property Control() As Control
    Public Property Child() As Thing

    Public Sub DoSomething()
        If Child IsNot Nothing Then
            Child.DoSomething()
        End If
    End Sub
End Class
I put a breakpoint on line 23, ran the project and clicked the Button. Execution stopped at the breakpoint and I checked the value of Control.Name and it was "TextBox1" as expected. I then hit F5 and execution stopped at the breakpoint a second time. I checked Control.Name again and it was "TextBox2" as expected. I then opened the Call Stack window and double-clicked on the first DoSomething call and checked Control.Name again. It was "TextBox1", as expected.
 

VBobCat

Well-known member
Joined
Sep 6, 2011
Messages
137
Location
S?o Paulo, Brazil
Programming Experience
3-5
Thank you very much. That will help me a lot for now.
I would like to know, anyway, is there some way for a class to store the name given upon each one of its instances, when they are declared? Or, in other fashion, is there a way an instance of a class can store the name given upon itself when it is declared?
 

jmcilhinney

VB.NET Forum Moderator
Staff member
Joined
Aug 17, 2004
Messages
14,295
Location
Sydney, Australia
Programming Experience
10+
I think you're mixing up objects and variables. Objects have no name. In this code:
Code:
Dim t1 As New Thing
Dim t2 As Thing = t1
Dim t3 As Thing = t2

t1 = Nothing
what's the name of the Thing object?
 

VBobCat

Well-known member
Joined
Sep 6, 2011
Messages
137
Location
S?o Paulo, Brazil
Programming Experience
3-5
Yes, I feel some conceptual weakness of mine here, plus some misuse of terms and a personal struggle with English, which is not my first language.

Taking your sample code:

I think you're mixing up objects and variables. Objects have no name. In this code:
Code:
Dim t1 As New Thing
Dim t2 As Thing = t1
Dim t3 As Thing = t2

t1 = Nothing
what's the name of the Thing object?
I would say (probably mistakenly) this:
- There is an object named Thing, but, as you say, this "name" exists only as a way we can call the class inside code.
- There is one instance of Thing stored in a variable named "t1"; therefore, this instance can be referred and called under the name "t1";
- The same instance is further referred also by variables "t2" and "t3", so the very instance first created and stored as "t1" can be referred and called also under the names "t2" and "t3";

I would get quite doubtful, then, if you asked me how can I be sure that everything I do to "t3" will happen to "t2" and "t1", especially because I don't know if Thing is a value type or a reference type. I'm aware there are things like object "copy" and "shallow copy", and I just read a text about the difference between the .Equals and the .ReferenceEquals methods of Object in Equals and ReferenceEquals Methods of the Object Object, so I'm digging my way to a better knowlege. I'm not there yet, though.

What helps confusing me, is that there are objects (mostly Form controls) that have a Name property that exposes, in string format, the same name of the variable that instances that particular control. So when I place a TextBox1 in my form, if I read its property name, it will say "TextBox1", won't it?

That said, what I only look for, is a way so my classes (especially those that will have lots of instances throughout the code) can tell, upon a breakpoint inside its methods, which instance is running at that point (in case there is not a property, such as the TextBox in that previous example, that could uniquely identify the instance). That would be relevant in this scenario:

Code:
Dim t1 As New Thing
Dim t2 As New Thing
Dim t3 As New Thing
Then I could break into DoSomething method and look for some variable or property that tells me, "I am t2", or anything like it.

Thank you very much for your kind attention.
 

VBobCat

Well-known member
Joined
Sep 6, 2011
Messages
137
Location
S?o Paulo, Brazil
Programming Experience
3-5
Suppose, for instance, that instead of Thing class, there is ControlHelper class and it takes a Control as parameter for its construction, plus a string that identifies some validation rule and string masking. Suppose, there are a lot of then (not necessarily packed together as follows):

Dim ControlHelper1 as New ControlHelper(TextBox1, "TXT")
Dim ControlHelper2 as New ControlHelper(TextBox2, "ADD")
Dim ControlHelper3 as New ControlHelper(TextBox3, "ZIP")
Dim ControlHelper4 as New ControlHelper(TextBox4, "EML")
Dim ControlHelper5 as New ControlHelper(TextBox5, "SSN")
Dim ControlHelper6 as New ControlHelper(TextBox5, "COD")
Dim ControlHelper7 as New ControlHelper(TextBox7, "TXT")
Dim ControlHelper8 as New ControlHelper(TextBox8, "TXT")
Dim ControlHelper9 as New ControlHelper(TextBox9, "TXT")


Did you notice my typo? ControlHelper6 takes TextBox5 as parameter, instead of TextBox6 which it should take. Then, the event handler built inside ControlHelper class will run twice when TextBox5 raises its event. Once inside instance ControlHelper5, when due "SSN" validation and mask rules will apply, and second time inside instance ControlHelper6, when wrong validation and maks will be imposed, destroying TextBox5 proper content.

So if I put a breakpoint inside the event handler, it will stop twice, and both will show "TextBox5" as the control implied. But none will tell me the name of the variable that stores that instance of ControlHelper. And then I won't be able to find where I made my typo, unless I sweep vast portions of code.

That was the firs reason I started this thread.
 

jmcilhinney

VB.NET Forum Moderator
Staff member
Joined
Aug 17, 2004
Messages
14,295
Location
Sydney, Australia
Programming Experience
10+
An object doesn't know anything about any variables that refer to it. Also, as I showed in post #5, multiple variables can refer to the same object. You seem to be under the impression that an object's "name" is the variable that refers to it but, it that was the case, what would be the name of an object that was referred to by multiple variables?

I think that this misconception comes from how controls are handled by the IDE. When you create a control in the designer and set the Name property, the IDE also creates a member variable with the same name. The IDE does that because it is logical but they are two different values. The Name property of a control is a String and it may or may not be the same as a member variable that refers to it. You can assign a control to a different variable but that doesn't change the value of its Name property. You can change the value of its Name property at run time but that doesn't change the variable that refers to them. Your class has no such Name property. If you want each object to have a name then you have to declare a Name property and set it on each instance.
 

VBobCat

Well-known member
Joined
Sep 6, 2011
Messages
137
Location
S?o Paulo, Brazil
Programming Experience
3-5
Ok, and you are right about the source of my misconception.

I'm so used to create controls with the IDE (since old days of VBA) that I never thought long and deep enough about the process. The fact is that the IDE does all the magic. When I click on a control's icon and place it on the Form design, the IDE creates a name (string), creates a variable with the same name, declares an instance of the control object onto this variable, and sets its "Name" property (string) to that first given name. And when I rename this control using the IDE, or better, typing a new name at the "Name" property field, then IDE also automatically renames the variable and all references to it throughout the project.

So it seems - to the naïf programmer who I actually am - they're the same thing, but they're not. My classes can't rely on that automation, so even if I give them a "Name" property, string-typed, they wouldn't foretell and store the name of the variables in which I store each instance of this class.

But then again, I must ask this: apart the debug resources of the graphic IDE, is there some way of programatically reaching, inside any given routine (sub or function), some data about the call stack, that is, from which other routine comes the call? Could the callee sub know the name of the caller sub, and the number of the line of the calling statement?
 

jmcilhinney

VB.NET Forum Moderator
Staff member
Joined
Aug 17, 2004
Messages
14,295
Location
Sydney, Australia
Programming Experience
10+
With regards to identifying your class instances, you could perhaps have each instance generate its own Guid and assign it to an Private field. That won't make it obvious which is which but it will make it easy to differentiate one from another.

As for your last question, take a look at the System.Diagnostics namespace and the StackFrame class, among others.
 
Top Bottom