C# Reference Types

Started by
5 comments, last by phil_t 11 years, 2 months ago

Hi there,

I've got a query about C# and returning reference types... if I have a class like :


class TestClass
{
  private int aNumber                 = 3;
  private string aString              = "hello";

  public int Number
  {
     get { return aNumber; }
     set { aNumber = value; }
  }

  public String TheString
  {
    get { return aString; }
  }
}

And I do the following :


TestClass testClass = new TestClass();

String aString = testClass.TheString;
System.Console.WriteLine( "String Value " + aString );
aString = "there";
System.Console.WriteLine( "Class String Value " + testClass.TheString );

The string value stored in the TestClass instance (testClass) isn't modified by :

aString = "there";

I thought that strings were a reference type... must be missing something here smile.png

Advertisement

They are a reference type, a reference to the (shared) value - not a reference to the variable.

They are a reference type, a reference to the (shared) value - not a reference to the variable.

Ah gotcha - so the local variable initially references the data in the class's variable, but the assignment operation changes the local variable's reference to another bit of data...

In c#, a String is immutable.

In c#, a String is immutable.

Regardless, in this case he is assigning a completely new value to a local variable - at this point it has nothing to do with TestClass.aString (i.e. this would be true even if he were using a class other than string - it has nothing to do with the fact that strings are immutable).

In c#, a String is immutable.


Regardless, in this case he is assigning a completely new value to a local variable - at this point it has nothing to do with TestClass.aString (i.e. this would be true even if he were using a class other than string - it has nothing to do with the fact that strings are immutable).


True, but the fact that Strings are immutable is important here.

Consider the following code:


public class RefClass
{
    public int IntProperty { get; private set; }

    public void DoStuff()
    {
        IntProperty++;
    }
}

public class ContainingClass
{
    private readonly RefClass _ref = new RefClass();

    public RefClass Ref
    {
        get { return _ref; }
    }
}

It's possible to do something like


ContainingClass c = new ContainingClass();
Debug.Assert(c.Ref.IntProperty == 0);
RefClass r = c.Ref;
r.DoStuff();
Debug.Assert(c.Ref.IntProperty == 1);

With a string, that wouldn't be possible because there are no operations that mutate a string.

if you think programming is like sex, you probably haven't done much of either.-------------- - capn_midnight

You're right, but I was specifically talking about assignment. In the original case, if you substitute string with StringBuilder (and have TestClass put "hello" in it by default), then by reassigning:


TestClass testClass = new TestClass();
StringBuilder aString = testClass.TheString;
System.Console.WriteLine( "String Value " + aString ); // "hello"
aString = new StringBuilder("there");
System.Console.WriteLine( "Class String Value " + testClass.TheString ); // Still "hello"

but, as in your "DoStuff" example:



TestClass testClass = new TestClass();
StringBuilder aString = testClass.TheString;
System.Console.WriteLine( "String Value " + aString ); // "hello"
aString.Clear();
aString.Append("there");
System.Console.WriteLine( "Class String Value " + testClass.TheString ); // "there"

This topic is closed to new replies.

Advertisement