Why does this work?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Gagan

    #1

    Why does this work?

    Hi All,

    I am new to VB.NET, and am confused by following code. The code
    basically obtains an instance of an object from a helper method. This
    helper method instantiates a new object, and returns it. But in its
    Finally block, it sets the returned object to Nothing. What perplexes
    me is that caller receives a valid object instance.

    The queston is: does this work because I am lucky, or this is really
    an expected behavior? Also, is this a correct coding practice? Will
    appreciate explanation.

    Thanks!

    Gagan
    =============

    Module Module1

    Class Salary
    Private m_Amount As Double = 0.0

    Public Property Amount() As Double
    Get
    Return m_Amount
    End Get
    Set(ByVal value As Double)
    m_Amount = value
    End Set
    End Property
    End Class

    Public Function GetSalary(ByVal dblAmount As Double) As Salary

    Dim pSalary As Salary = Nothing

    Try
    pSalary = New Salary()
    pSalary.Amount = dblAmount

    Return pSalary
    Catch ex As Exception
    '
    Finally
    pSalary = Nothing
    End Try

    End Function


    Sub Main()
    Dim pSalary As Salary = GetSalary(100.0 )
    System.Console. WriteLine(pSala ry.Amount)
    End Sub

    End Module

  • Armin Zingler

    #2
    Re: Why does this work?

    "Gagan" <Gagan.Gajabaha ria@gmail.comsc hrieb
    Hi All,
    >
    I am new to VB.NET, and am confused by following code. The code
    basically obtains an instance of an object from a helper method.
    This helper method instantiates a new object, and returns it. But in
    its Finally block, it sets the returned object to Nothing. What
    perplexes me is that caller receives a valid object instance.
    >
    The queston is: does this work because I am lucky, or this is really
    an expected behavior?
    This is expected. You set the value of the local variable pSalary in the
    Finally block, but when the Return statement has been executed (before), the
    variable was not nothing, thus the function return value is not Nothing.
    What you do to the local variable after setting the return value has no
    effect on the return value.
    Also, is this a correct coding practice?
    Which practice? If you mean setting local variables to Nothing before the
    end of the procedure, only very few people do this. I don't because it's
    superfluous because the variable is running out of scope anyways.

    Armin

    Will
    appreciate explanation.
    >
    Thanks!
    >
    Gagan
    =============
    >
    Module Module1
    >
    Class Salary
    Private m_Amount As Double = 0.0
    >
    Public Property Amount() As Double
    Get
    Return m_Amount
    End Get
    Set(ByVal value As Double)
    m_Amount = value
    End Set
    End Property
    End Class
    >
    Public Function GetSalary(ByVal dblAmount As Double) As Salary
    >
    Dim pSalary As Salary = Nothing
    >
    Try
    pSalary = New Salary()
    pSalary.Amount = dblAmount
    >
    Return pSalary
    Catch ex As Exception
    '
    Finally
    pSalary = Nothing
    End Try
    >
    End Function
    >
    >
    Sub Main()
    Dim pSalary As Salary = GetSalary(100.0 )
    System.Console. WriteLine(pSala ry.Amount)
    End Sub
    >
    End Module
    >

    Comment

    • Gagan

      #3
      Re: Why does this work?

      On Aug 5, 2:53 am, "Armin Zingler" <az.nos...@free net.dewrote:
      >
      This is expected. You set the value of the local variable pSalary in the
      Finally block, but when the Return statement has been executed (before), the
      variable was not nothing, thus the function return value is not Nothing.
      What you do to the local variable after setting the return value has no
      effect on the return value.
      Ok, I understand. The variable is local, but it points to the object
      that is allocated on the heap.

      I have another question: what exactly happens when the return
      statement is executed? It apparently doesn't return the control to
      the caller immediately. Probably it pushes the return value on the
      stack, so that caller can pop it - and later changes to the local
      variable doesn't affect the value on the stack. Is this correct
      thinking?

      Thanks for the response.

      Gagan


      Comment

      • Cor Ligthert[MVP]

        #4
        Re: Why does this work?

        Gagan,
        Ok, I understand. The variable is local, but it points to the object
        that is allocated on the heap.
        >
        This is absolute not what Armin wrote. Just read his message again.

        Cor

        Comment

        • Gagan

          #5
          Re: Why does this work?

          On Aug 5, 9:40 pm, "Cor Ligthert[MVP]" <notmyfirstn... @planet.nl>
          wrote:
          Gagan,
          >
          Ok, I understand. The variable is local, but it points to the object
          that is allocated on the heap.
          >
          This is absolute not what Armin wrote. Just read his message again.
          >
          Cor
          I read his message again. Can you tell me where the object is created
          as a result of calling the New() ?

          Thanks.

          Gagan



          Comment

          • Dave Griffiths

            #6
            Re: Why does this work?

            At the start of the Try Block

            Try
            pSalary = New Salary()
            pSalary.Amount = dblAmount

            Return pSalary

            --
            Dave Griffiths


            Gagan wrote:
            On Aug 5, 9:40 pm, "Cor Ligthert[MVP]" <notmyfirstn... @planet.nl>
            wrote:
            Gagan,
            Ok, I understand. The variable is local, but it points to the
            object that is allocated on the heap.
            This is absolute not what Armin wrote. Just read his message again.

            Cor
            >
            I read his message again. Can you tell me where the object is created
            as a result of calling the New() ?
            >
            Thanks.
            >
            Gagan

            Comment

            • Armin Zingler

              #7
              Re: Why does this work?

              "Gagan" <Gagan.Gajabaha ria@gmail.comsc hrieb
              On Aug 5, 2:53 am, "Armin Zingler" <az.nos...@free net.dewrote:
              >

              This is expected. You set the value of the local variable pSalary
              in the Finally block, but when the Return statement has been
              executed (before), the variable was not nothing, thus the function
              return value is not Nothing. What you do to the local variable
              after setting the return value has no effect on the return value.
              >
              Ok, I understand. The variable is local, but it points to the object
              that is allocated on the heap.
              You probably assume that the return value is a reference to the local
              variable, but it is not. If that was the case, you were right.

              What happens is, the Return statement sets the function return value. The
              return value is a reference to an object. The caller gets a copy of the
              reference to the object. In general, after modifying the source of a copy,
              the copy remains unchanged. In your case, the local variable holding the
              reference to the object is copied. Changing the local variable doesn't
              affect the copy, i.e. the function return value, made before.
              I have another question: what exactly happens when the return
              statement is executed? It apparently doesn't return the control to
              the caller immediately. Probably it pushes the return value on the
              stack, so that caller can pop it - and later changes to the local
              variable doesn't affect the value on the stack. Is this correct
              thinking?
              The return statement
              1. sets the function return value
              2. processes the finally sections of enclosing try-sections (this includes
              using sections)
              3. exits the function.

              The function return value is not returned on the stack. Internally, 32-Bit
              values are usually returned in a processor registers (EAX). This includes
              object references (at least on a 32-Bit target plattform) that are also
              32-Bit values. But that's implementation detail, so it may change in future
              runtime/JIT versions. Calling conventions:




              Armin

              Comment

              • =?ISO-8859-1?Q?G=F6ran_Andersson?=

                #8
                Re: Why does this work?

                Gagan wrote:
                On Aug 5, 9:40 pm, "Cor Ligthert[MVP]" <notmyfirstn... @planet.nl>
                wrote:
                >Gagan,
                >>
                >>Ok, I understand. The variable is local, but it points to the object
                >>that is allocated on the heap.
                >This is absolute not what Armin wrote. Just read his message again.
                >>
                >Cor
                >
                I read his message again. Can you tell me where the object is created
                as a result of calling the New() ?
                >
                Thanks.
                >
                Gagan
                >
                On the heap. Just as you said. :)

                You were absolutely correct in your analysis.

                The variable is local, and it's a reference to the object that is
                created on the heap. When you copy the reference into the return value,
                there are two references to the same object. Changing the reference in
                the local variable after the return value has been set doesn't affect
                the return value and doesn't affect the object on the heap.

                --
                Göran Andersson
                _____
                Göran Anderssons privata hemsida.

                Comment

                • Bill McCarthy

                  #9
                  Re: Why does this work?

                  Hi Gagan,

                  Let me try to explain form a different approach.

                  First in the Finally block change the pSalary = Nothing to something like
                  pSalary.Amount = 20
                  You'll see the output is 20. So the pSalary variable is pointing at the
                  Salary object that is returned.

                  Now change the code back to how you had it, setting pSalary to Nothing.
                  What that does is means the pSalary varaible is no longer pointing to the
                  object in the heap. That Object however has been assigned to functions
                  return value already though so changes to the pSalary variable make no
                  changes to what is returned, but changes to the Object itself do.

                  So the behaviorual equivalent of the code is :


                  Public Function GetSalary(ByVal dblAmount As Double) As Salary

                  Dim hidden_return_v alue_on_stack As Salary
                  Dim pSalary As Salary = Nothing

                  Try
                  pSalary = New Salary()
                  pSalary.Amount = dblAmount

                  hidden_return_v alue_on_stack = pSalary
                  Catch ex As Exception
                  '
                  Finally
                  pSalary = Nothing
                  End Try

                  ' automatically returns hidden_return_v alue_on_stack
                  End Function




                  In VB you can actually write this using the method name, but I prefer not to
                  as the code can be more confusing especially is there are any overloads, eg:

                  Public Function GetSalary(ByVal dblAmount As Double) As Salary

                  Dim pSalary As Salary = Nothing

                  Try
                  pSalary = New Salary()
                  pSalary.Amount = dblAmount

                  GetSalary = pSalary
                  Catch ex As Exception
                  '
                  Finally
                  pSalary = Nothing
                  End Try

                  ' automatically returns GetSalary
                  End Function





                  "Gagan" <Gagan.Gajabaha ria@gmail.comwr ote in message
                  news:1186300271 .092069.268550@ g12g2000prg.goo glegroups.com.. .
                  Hi All,
                  >
                  I am new to VB.NET, and am confused by following code. The code
                  basically obtains an instance of an object from a helper method. This
                  helper method instantiates a new object, and returns it. But in its
                  Finally block, it sets the returned object to Nothing. What perplexes
                  me is that caller receives a valid object instance.
                  >
                  The queston is: does this work because I am lucky, or this is really
                  an expected behavior? Also, is this a correct coding practice? Will
                  appreciate explanation.
                  >
                  Thanks!
                  >
                  Gagan
                  =============
                  >
                  Module Module1
                  >
                  Class Salary
                  Private m_Amount As Double = 0.0
                  >
                  Public Property Amount() As Double
                  Get
                  Return m_Amount
                  End Get
                  Set(ByVal value As Double)
                  m_Amount = value
                  End Set
                  End Property
                  End Class
                  >
                  Public Function GetSalary(ByVal dblAmount As Double) As Salary
                  >
                  Dim pSalary As Salary = Nothing
                  >
                  Try
                  pSalary = New Salary()
                  pSalary.Amount = dblAmount
                  >
                  Return pSalary
                  Catch ex As Exception
                  '
                  Finally
                  pSalary = Nothing
                  End Try
                  >
                  End Function
                  >
                  >
                  Sub Main()
                  Dim pSalary As Salary = GetSalary(100.0 )
                  System.Console. WriteLine(pSala ry.Amount)
                  End Sub
                  >
                  End Module
                  >

                  Comment

                  • Gagan

                    #10
                    Re: Why does this work?

                    On Aug 6, 7:42 am, "Bill McCarthy" <B...@NOSPAM.co mwrote:
                    Hi Gagan,
                    >
                    Let me try to explain form a different approach.
                    >
                    First in the Finally block change the pSalary = Nothing to something like
                    pSalary.Amount = 20
                    You'll see the output is 20. So the pSalary variable is pointing at the
                    Salary object that is returned.
                    Bill,

                    That's exactly what I had done to figure out that object was created
                    on heap and pSalary was just a pointer to it :) Thanks!

                    Gagan

                    Comment

                    • Gagan

                      #11
                      Re: Why does this work?

                      On Aug 5, 11:59 pm, "Armin Zingler" <az.nos...@free net.dewrote:
                      "Gagan" <Gagan.Gajabaha ...@gmail.comsc hrieb
                      >
                      On Aug 5, 2:53 am, "Armin Zingler" <az.nos...@free net.dewrote:
                      >
                      This is expected. You set the value of the local variable pSalary
                      in the Finally block, but when the Return statement has been
                      executed (before), the variable was not nothing, thus the function
                      return value is not Nothing. What you do to the local variable
                      after setting the return value has no effect on the return value.
                      >
                      Ok, I understand. The variable is local, but it points to the object
                      that is allocated on the heap.
                      <Snip>

                      Thanks, Armin, for the explanation.

                      Gagan





                      Comment

                      • Gagan

                        #12
                        Re: Why does this work?

                        On Aug 5, 11:59 pm, "Armin Zingler" <az.nos...@free net.dewrote:
                        "Gagan" <Gagan.Gajabaha ...@gmail.comsc hrieb
                        >
                        On Aug 5, 2:53 am, "Armin Zingler" <az.nos...@free net.dewrote:
                        >
                        This is expected. You set the value of the local variable pSalary
                        in the Finally block, but when the Return statement has been
                        executed (before), the variable was not nothing, thus the function
                        return value is not Nothing. What you do to the local variable
                        after setting the return value has no effect on the return value.
                        >
                        Ok, I understand. The variable is local, but it points to the object
                        that is allocated on the heap.
                        >
                        You probably assume that the return value is a reference to the local
                        variable, but it is not. If that was the case, you were right.
                        >
                        <snip>

                        Armin,

                        I found that my real reason for the confusion was my assumption that
                        return statement must be returning control back to the caller. And, in
                        my infinite wisdom, I also thought that compiler must be smart enough
                        to generate the code such that it would execute the finally block
                        before the return is executed. But that is not so, as I learnt.
                        Thanks!

                        Gagan



                        Comment

                        • Gagan

                          #13
                          Re: Why does this work?

                          On Aug 5, 12:51 am, Gagan <Gagan.Gajabaha ...@gmail.comwr ote:
                          Hi All,
                          >
                          I am new to VB.NET, and am confused by following code. The code
                          basically obtains an instance of an object from a helper method. This
                          helper method instantiates a new object, and returns it. But in its
                          Finally block, it sets the returned object to Nothing. What perplexes
                          me is that caller receives a valid object instance.
                          >
                          The queston is: does this work because I am lucky, or this is really
                          an expected behavior? Also, is this a correct coding practice? Will
                          appreciate explanation.
                          >
                          Many thanks to everyone for their responses, I really learnt something
                          out of this.

                          Gagan


                          Comment

                          Working...