Basic Question: string reference type

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

    Basic Question: string reference type

    Hello all,

    In C# string is a reference type but I learned that string is different from
    other reference types such as class. For example, if you pass a string
    argument to a method and then change the value in that method the
    modification will not be visible outside the method. However this is not
    true for classes. In my example I am not using ref keyword.

    Thanks for feedback.


  • Michael Mayer

    #2
    Re: Basic Question: string reference type

    Correct, the terminology used is that strings are immutable reference types.
    So they don't behave quite like other reference types. Once defined, a
    string cannot change value. However, a variable holding a reference to a
    string may certainly be assigned a new string object. This is often
    encountered in the following:

    string mystr = "Good morning.";
    mystr.Replace ("morning", "evening"); // does nothing
    mystr = mystr.Replace ("morning", "evening"); // expected behavior

    Not really about strings in particular, but here's some good references on
    reference / value types if you want more info:

    Pobox has been discontinued as a separate service, and all existing customers moved to the Fastmail platform.

    Pobox has been discontinued as a separate service, and all existing customers moved to the Fastmail platform.

    and

    (by your's truly)

    --
    Mike Mayer

    mike@mag37.com


    "Nader" <nader_shayan@h otmail.com> wrote in message
    news:eYCfUL%23e DHA.2748@TK2MSF TNGP11.phx.gbl. ..[color=blue]
    > Hello all,
    >
    > In C# string is a reference type but I learned that string is different[/color]
    from[color=blue]
    > other reference types such as class. For example, if you pass a string
    > argument to a method and then change the value in that method the
    > modification will not be visible outside the method. However this is not
    > true for classes. In my example I am not using ref keyword.
    >
    > Thanks for feedback.
    >
    >[/color]


    Comment

    • Nader

      #3
      Re: Basic Question: string reference type

      Thanks Mike,

      I was just wondering what is happening behind the scenes that make strings
      act differently.


      Comment

      • Michael Mayer

        #4
        Re: Basic Question: string reference type

        "Nader" <nader_shayan@h otmail.com> wrote in message
        news:euZGz7$eDH A.3248@tk2msftn gp13.phx.gbl...[color=blue]
        > Thanks Mike,
        >
        > I was just wondering what is happening behind the scenes that make strings
        > act differently.[/color]

        I don't think there's really much "beind the scenes" magic. There is no
        method that allows you to change a string, therefore it is immutable. You
        can make your own class that is immutable pretty easily:

        (pardon this code, it's all written on the fly in the newsreader, so there
        are surely some grammatical mistakes)

        public sealed class ImmutableComple xNumber {
        public ImmutableComple xNumber (double real, double imag) {
        this.real = real;
        this.imag = imag;
        }
        double real;
        double imag;

        public double AbsoluteValue {
        get { return (real * real) + (imag * imag); }
        }

        public ImmutableComple xNumber Add (ImmutableCompl exNumber x) {
        return new ImmutableComple xNumber (this.real + x.real, this.imag +
        x.imag);
        }
        }

        There is no way for a user to actually change the value of an instance of
        ImmutableComple xNumber once the've created it. Even add will simply return a
        new number. The class is sealed, real and imag are private, and there are no
        publicly accesible methods (other than the constructor) that will change
        those two private fields. Pretty much the same for strings.

        Now strings have the additional benefit of being known by the CLR so it can
        do cool tricks like string interning and other optimizations. Here's an
        article I've run across in the past that has some details on inner workings
        of the string class.




        Hope that answers your questions.

        --
        Mike Mayer

        mike@mag37.com



        Comment

        • Jon Skeet

          #5
          Re: Basic Question: string reference type

          Nader <nader_shayan@h otmail.com> wrote:[color=blue]
          > In C# string is a reference type but I learned that string is different from
          > other reference types such as class.[/color]

          No it's not. Not really.
          [color=blue]
          > For example, if you pass a string
          > argument to a method and then change the value in that method the
          > modification will not be visible outside the method.[/color]

          Changing the value of a reference variable does *not* make any change
          in the object itself.
          [color=blue]
          > However this is not true for classes.[/color]

          Yes it is.

          Here's an example of what I think you mean:

          using System;

          public class Test
          {
          static void Main()
          {
          string x = "hello";
          Foo (x);
          Console.WriteLi ne (x);
          }

          static void Foo(string y)
          {
          y = "world";
          }
          }

          The above prints hello, but you'd expect it to print world. Now, that's
          exactly the same as:


          public class Test
          {
          static void Main()
          {
          ArrayList al = new ArrayList();
          al.Add ("hello");
          Foo (al);
          Console.WriteLi ne (al[0]);
          }

          static void Foo(ArrayList y)
          {
          y = new ArrayList();
          y.Add ("world");
          }
          }

          Note that we're changing the *value of y* in both cases, not the data
          within the object that the original reference points to.

          Strings are absolutely reference types - but you need to be clear about
          the difference between changing which object a variable's value refers
          to and changing the *contents* of the object a variable's value refers
          to.

          See http://www.pobox.com/~skeet/csharp/parameters.html and
          http://www.pobox.com/~skeet/csharp/memory.html for more details.

          --
          Jon Skeet - <skeet@pobox.co m>
          Pobox has been discontinued as a separate service, and all existing customers moved to the Fastmail platform.

          If replying to the group, please do not mail me too

          Comment

          • Jon Skeet

            #6
            Re: Basic Question: string reference type

            Michael Mayer <mike@mag37.com > wrote:[color=blue]
            > Correct, the terminology used is that strings are immutable reference types.
            > So they don't behave quite like other reference types.[/color]

            They do! They behave exactly like other reference types. It so happens
            that you can't change them, but that's in common with a lot of other
            reference types, and it's not "special" at all - it's not like there's
            another rule to learn, it's just applying the normal rules.

            The only "tricky" thing about strings is string literals - and they're
            just references to string objects which will exist by the time you use
            the literal, and are interned so that the same literal will always
            refer to the same instance within an application.

            --
            Jon Skeet - <skeet@pobox.co m>
            Pobox has been discontinued as a separate service, and all existing customers moved to the Fastmail platform.

            If replying to the group, please do not mail me too

            Comment

            • Nader

              #7
              Re: Basic Question: string reference type

              Please look at the piece of code below.

              Even though my argument list in test(...) method does not include ref
              keyword the result is visible in the Main() function and you get "Hello from
              testClass".

              This is not the case when I replace myString class with a simple string.

              using System;

              class myString
              {
              public myString()
              {
              str1 = "Hello from myString";
              }
              public string str1;
              }

              class testClass
              {
              public void test(myString astr)
              {
              astr.str1 = "Hello from testClass";
              }
              }

              class theApp
              {
              public static void Main()
              {
              testClass tc = new testClass();
              myString ms = new myString();
              tc.test(ms);
              Console.WriteLi ne("{0}", ms.str1);
              }
              }




              Comment

              • Michael Mayer

                #8
                Re: Basic Question: string reference type

                Your class myString is NOT an immutable class (the way string is) since you
                made str1 a public field of class myString (see my previous post with the
                complex number example - this would be an immutable class).

                I would suspect that if you had read those articles that Jon and I wrote
                (posted previously) they will clear up some of your mis-understanding. I'll
                try here briefly, but I must insist that you go read Jon's or my articles (I
                think mine is more geared toward a beginner to C#, while Jon's uses more
                accurate, technical verbage).

                However, we can rewrite your example below to do the same thing as you
                mentioned in your first post:

                public void test(myString astr)
                {
                astr = new myString ("Hello from testClass";)
                }

                Note that here in my version of test, I am trying to change the VALUE of
                astr (which is a reference to a class). Since astr is passed by value, this
                has no affect in the calling function. This is what you mentioned doing in
                your first post - changing a string in a method, probably as follows:

                public void testOP (string mystring)
                {
                mystring = "new string";
                }

                In your version (below) you are not changing the value of astr, but rather,
                the value of str1 in an instance of myString class. Since both testClass and
                theApp reference that same instance, you will see the change both places.

                Another note, you might find the following useful on naming conventions, it
                will make your code more immediately readable by others (that is, classes
                and methods should be capitalized in C#)



                --
                Mike Mayer

                mike@mag37.com



                "Nader" <nader_shayan@h otmail.com> wrote in message
                news:ei23U7IfDH A.2984@TK2MSFTN GP11.phx.gbl...[color=blue]
                > Please look at the piece of code below.
                >
                > Even though my argument list in test(...) method does not include ref
                > keyword the result is visible in the Main() function and you get "Hello fr[/color]
                om[color=blue]
                > testClass".
                >
                > This is not the case when I replace myString class with a simple string.
                >
                > using System;
                >
                > class myString
                > {
                > public myString()
                > {
                > str1 = "Hello from myString";
                > }
                > public string str1;
                > }
                >
                > class testClass
                > {
                > public void test(myString astr)
                > {
                > astr.str1 = "Hello from testClass";
                > }
                > }
                >
                > class theApp
                > {
                > public static void Main()
                > {
                > testClass tc = new testClass();
                > myString ms = new myString();
                > tc.test(ms);
                > Console.WriteLi ne("{0}", ms.str1);
                > }
                > }
                >
                >
                >
                >[/color]


                Comment

                • Michael Mayer

                  #9
                  Re: Basic Question: string reference type

                  "Jon Skeet" <skeet@pobox.co m> wrote in message
                  news:MPG.19d0c2 173223a0bc9896b 5@news.microsof t.com...[color=blue]
                  > Michael Mayer <mike@mag37.com > wrote:[color=green]
                  > > Correct, the terminology used is that strings are immutable reference[/color][/color]
                  types.[color=blue][color=green]
                  > > So they don't behave quite like other reference types.[/color]
                  >
                  > They do! They behave exactly like other reference types. It so happens
                  > that you can't change them, but that's in common with a lot of other
                  > reference types, and it's not "special" at all - it's not like there's
                  > another rule to learn, it's just applying the normal rules.[/color]

                  Jon,
                  My first post didn't say exactly what I meant for it to have said. I think
                  my second post clarified what I meant a little better.

                  I was trying to get across something you mentioned on one of your pages:

                  "Note that many types (such as string) appear in some ways to be value
                  types, but in fact are reference types. These are known as immutable types."

                  I should have mentioned that they still follow all the rules of reference
                  types, with the added benefit that, like value types, you don't have to
                  worry about them changing when passed as parameters to other methods.


                  --
                  Mike Mayer

                  mike@mag37.com



                  Comment

                  Working...