Using 'ref' when already reference variable

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

    Using 'ref' when already reference variable

    Is there any harm in passing an object into a method with the 'ref'
    keyword if the object is already a reference variable? If not, is
    there any benefit?

  • John A. Bailo

    #2
    Re: Using 'ref' when already reference variable

    Doug wrote:[color=blue]
    > Is there any harm in passing an object into a method with the 'ref'
    > keyword if the object is already a reference variable? If not, is
    > there any benefit?
    >[/color]

    That is the default for objects.

    Comment

    • David Anton

      #3
      RE: Using 'ref' when already reference variable

      Using 'ref' for an object means that the method may change which object is
      being pointed to. So, yes - there is some harm in using 'ref' when you don't
      want to allow the method to change which object is being pointed to.

      But you may not have a choice - if the method has a 'ref' param, you must
      use the 'ref' keyword on the argument (in C#).
      --
      David Anton
      Source code converters: Convert between C#, C++, Java, VB, and Python with the most accurate and reliable source code converters

      Instant C#: VB.NET to C# Converter
      Instant VB: C# to VB.NET Converter
      Instant C++: C# to C++ Converter
      Instant J#: VB.NET to J# Converter



      "Doug" wrote:
      [color=blue]
      > Is there any harm in passing an object into a method with the 'ref'
      > keyword if the object is already a reference variable? If not, is
      > there any benefit?
      >
      >[/color]

      Comment

      • Cool Guy

        #4
        Re: Using 'ref' when already reference variable

        "John A. Bailo" <jabailo@texeme .com> wrote:
        [color=blue][color=green]
        >> Is there any harm in passing an object into a method with the 'ref'
        >> keyword if the object is already a reference variable? If not, is
        >> there any benefit?[/color]
        >
        > That is the default for objects.[/color]

        Actually the default (for everything) is *by-value* passing. See
        <http://www.yoda.arachs ys.com/csharp/parameters.html >.

        Comment

        • John A. Bailo

          #5
          Re: Using 'ref' when already reference variable

          Cool Guy wrote:[color=blue]
          > "John A. Bailo" <jabailo@texeme .com> wrote:
          >
          >[color=green][color=darkred]
          >>>Is there any harm in passing an object into a method with the 'ref'
          >>>keyword if the object is already a reference variable? If not, is
          >>>there any benefit?[/color]
          >>
          >>That is the default for objects.[/color]
          >
          >
          > Actually the default (for everything) is *by-value* passing. See
          > <http://www.yoda.arachs ys.com/csharp/parameters.html >.[/color]

          I guess (from your article) this is what I meant to say:

          "This difference is absolutely crucial to understanding parameter
          passing in C#, and is why I believe it is highly confusing to say that
          objects are passed by reference by default instead of the correct
          statement that object references are passed by value by default."

          Comment

          • Doug

            #6
            Re: Using 'ref' when already reference variable

            All of this has been very helpful, but has lead me to another question.
            Say I have a method like so:

            private bool TestMethod(myFi rstClass oFirstClass, mySecondClass
            oSecondClass, myThirdClass oThirdClass)
            {
            ...code here
            }

            and I'm not concerned with whether or not they set the value of those
            objects to null inside this method or not but do want them to have the
            ability to modify properties of the three class within them (which they
            can regardless if they pass the parameters with the 'ref' keyword or
            not).

            What I am concerned with is that I may call this method many, many
            times under different threads. From what I understand of the reading I
            did of the document you put in your response, that would mean that each
            time this method is called a new instance of each class is created of
            the variables since they are not passed with the 'ref' keyword. From a
            memory point of view this would be bad wouldn't it?

            Comment

            • Cool Guy

              #7
              Re: Using 'ref' when already reference variable

              Doug <dnlwhite@dtgne t.com> wrote:
              [color=blue]
              > private bool TestMethod(myFi rstClass oFirstClass, mySecondClass
              > oSecondClass, myThirdClass oThirdClass)
              > {
              > ...code here
              > }
              >
              > [...]
              >
              > From what I understand of the reading I
              > did of the document you put in your response, that would mean that each
              > time this method is called a new instance of each class is created of
              > the variables since they are not passed with the 'ref' keyword.[/color]

              Your understanding is wrong. No new instances are created whether or not
              'ref' is used.

              Consider (MyClass is a class):

              void Foo(MyClass myClass) {
              ...
              }

              When myClass is passed, it is passed by value. The value that is passed is
              an /object reference/, since MyClass is a reference type. (An
              /object reference/ is like a pointer to an object on the heap.)

              Consider (MyClass is a class):

              void Foo(ref MyClass myClass) {
              ...
              }

              When myClass is passed, it is passed by reference. The passed reference
              **refers to** the /object reference/. (A reference to an /object reference/
              is kind of like a pointer to a pointer.)

              If this still isn't clear perhaps try reading the article I linked to
              *again*, asking here about any parts you're unsure about.

              Comment

              • Doug

                #8
                Re: Using 'ref' when already reference variable

                Thanks. I figured out after I posted previously that I still didn't
                get it. It's a pointer thing and I always get confused by that. But I
                think I got it now. Thank you!

                Comment

                • John A. Bailo

                  #9
                  Re: Using 'ref' when already reference variable

                  Cool Guy wrote:
                  [color=blue]
                  > When myClass is passed, it is passed by reference. The passed reference
                  > **refers to** the /object reference/. (A reference to an /object reference/
                  > is kind of like a pointer to a pointer.)[/color]

                  Well, isn't it just more like a pointer to an object -- or value?

                  Another thing, they say it's an object reference passed by value to the
                  method.

                  Ok, so that means if the object(class instance) gets an update (member
                  changes) that when I use the handle to the object, it should reflect the
                  updated value. Right?

                  And can if you did use the 'ref' keyword, wouldn't it then pass an
                  object reference to an object by reference instead of by value?

                  That would mean that would be more like a pointer to a pointer. What
                  that means is that I could change the object that is being pointed to by
                  the first pointer and the second reference would automatically be
                  pointing to that 2nd object.


                  Comment

                  • Cool Guy

                    #10
                    Re: Using 'ref' when already reference variable

                    "John A. Bailo" <jabailo@texeme .com> wrote:
                    [color=blue]
                    > Cool Guy wrote:
                    >[color=green]
                    >> When myClass is passed, it is passed by reference. The passed reference
                    >> **refers to** the /object reference/. (A reference to an /object reference/
                    >> is kind of like a pointer to a pointer.)[/color]
                    >
                    > Well, isn't it just more like a pointer to an object -- or value?[/color]

                    That sounds more like the case where ref *isn't* used. In the part you
                    quoted I was referring to it being used.
                    [color=blue]
                    > Another thing, they say it's an object reference passed by value to the
                    > method.[/color]

                    In the case of ref *not* being used, yeah.
                    [color=blue]
                    > Ok, so that means if the object(class instance) gets an update (member
                    > changes) that when I use the handle to the object, it should reflect the
                    > updated value. Right?[/color]

                    Yep. That's why the following works prints 'testing', not 'test':

                    using System;
                    using System.Text;

                    class Test {
                    static void Main() {
                    StringBuilder sb = new StringBuilder(" test");
                    Append(sb);
                    Console.WriteLi ne(sb);
                    }

                    static void Append(StringBu ilder sb) {
                    sb.Append("ing" );
                    }
                    }
                    [color=blue]
                    > And can if you did use the 'ref' keyword, wouldn't it then pass an
                    > object reference to an object by reference instead of by value?[/color]

                    An object reference would be passed to a method by reference instead of by
                    value.
                    [color=blue]
                    > That would mean that would be more like a pointer to a pointer. What
                    > that means is that I could change the object that is being pointed to by
                    > the first pointer and the second reference would automatically be
                    > pointing to that 2nd object.[/color]

                    Indeed. This is how I tend to visualise it (with the arrows meaning 'refers
                    to'):

                    reference --> object reference --> object (on heap)

                    The object reference in the middle can be changed via the reference on the
                    left to refer to another object on the heap (or null).

                    For example, in the following 'False' is printed:

                    using System;
                    using System.Text;

                    class Test {
                    static void Main() {
                    StringBuilder sb = new StringBuilder(" test");
                    StringBuilder original = sb;

                    PseudoAppend(re f sb);
                    Console.WriteLi ne(Object.Refer enceEquals(sb, original));
                    }

                    static void PseudoAppend(re f StringBuilder sb) {
                    // modify the original object reference to refer to
                    // a new object
                    sb = new StringBuilder(" testing");
                    }
                    }

                    Had the StringBuilder been passed by value instead (i.e. had 'ref' not been
                    used) 'True' would've been printed as the object reference Main.sb would
                    not have been modifiable from within PseudoAppend.

                    Comment

                    • John A. Bailo

                      #11
                      Re: Using 'ref' when already reference variable


                      This pretty much answers all cases /except/ how do you pass an object by
                      value...where it clones the object so I can make changes to it without
                      changing the original?


                      Cool Guy wrote:[color=blue]
                      > "John A. Bailo" <jabailo@texeme .com> wrote:
                      >
                      >[color=green]
                      >>Cool Guy wrote:
                      >>
                      >>[color=darkred]
                      >>>When myClass is passed, it is passed by reference. The passed reference
                      >>>**refers to** the /object reference/. (A reference to an /object reference/
                      >>>is kind of like a pointer to a pointer.)[/color]
                      >>
                      >>Well, isn't it just more like a pointer to an object -- or value?[/color]
                      >
                      >
                      > That sounds more like the case where ref *isn't* used. In the part you
                      > quoted I was referring to it being used.
                      >
                      >[color=green]
                      >>Another thing, they say it's an object reference passed by value to the
                      >>method.[/color]
                      >
                      >
                      > In the case of ref *not* being used, yeah.
                      >
                      >[color=green]
                      >>Ok, so that means if the object(class instance) gets an update (member
                      >>changes) that when I use the handle to the object, it should reflect the
                      >>updated value. Right?[/color]
                      >
                      >
                      > Yep. That's why the following works prints 'testing', not 'test':
                      >
                      > using System;
                      > using System.Text;
                      >
                      > class Test {
                      > static void Main() {
                      > StringBuilder sb = new StringBuilder(" test");
                      > Append(sb);
                      > Console.WriteLi ne(sb);
                      > }
                      >
                      > static void Append(StringBu ilder sb) {
                      > sb.Append("ing" );
                      > }
                      > }
                      >
                      >[color=green]
                      >>And can if you did use the 'ref' keyword, wouldn't it then pass an
                      >>object reference to an object by reference instead of by value?[/color]
                      >
                      >
                      > An object reference would be passed to a method by reference instead of by
                      > value.
                      >
                      >[color=green]
                      >>That would mean that would be more like a pointer to a pointer. What
                      >>that means is that I could change the object that is being pointed to by
                      >>the first pointer and the second reference would automatically be
                      >>pointing to that 2nd object.[/color]
                      >
                      >
                      > Indeed. This is how I tend to visualise it (with the arrows meaning 'refers
                      > to'):
                      >
                      > reference --> object reference --> object (on heap)
                      >
                      > The object reference in the middle can be changed via the reference on the
                      > left to refer to another object on the heap (or null).
                      >
                      > For example, in the following 'False' is printed:
                      >
                      > using System;
                      > using System.Text;
                      >
                      > class Test {
                      > static void Main() {
                      > StringBuilder sb = new StringBuilder(" test");
                      > StringBuilder original = sb;
                      >
                      > PseudoAppend(re f sb);
                      > Console.WriteLi ne(Object.Refer enceEquals(sb, original));
                      > }
                      >
                      > static void PseudoAppend(re f StringBuilder sb) {
                      > // modify the original object reference to refer to
                      > // a new object
                      > sb = new StringBuilder(" testing");
                      > }
                      > }
                      >
                      > Had the StringBuilder been passed by value instead (i.e. had 'ref' not been
                      > used) 'True' would've been printed as the object reference Main.sb would
                      > not have been modifiable from within PseudoAppend.[/color]

                      Comment

                      • Cool Guy

                        #12
                        Re: Using 'ref' when already reference variable

                        "John A. Bailo" <jabailo@texeme .com> wrote:
                        [color=blue]
                        > This pretty much answers all cases /except/ how do you pass an object by
                        > value...where it clones the object so I can make changes to it without
                        > changing the original?[/color]

                        You could make it a struct instead of a class. Then the *value* gets passed
                        by value instead of the *reference* getting passed by value.

                        Or you could make the class immutable - then no state can be changed
                        anyway.

                        Or you could manually clone the instance and then pass the reference to
                        this *cloned* instance instead of passing the reference to the *original*
                        instance.

                        Comment

                        Working...