Search code examples
c#ref

Can you reference a reference?


Can you pass a reference to a reference sort of how passing a Control behaves?

I notice that when you pass a control into the constructor it actually passes a reference to that control and then if you assign another control to that control it is not copying the value but actually copying the reference itself! Why can't this be accomplished with regular variables or at least with the ref keyword?

For example...

public class Test : Form
{

Test()
{
InitializeComponent();
}
Test_Load(object sender, EventArgs e)
{
new Test2((Control)MyTextBox).ShowDialog();
}

}

public class Test2 : Form
{
Public Control x_
Test2(Control x)
{
x_=x;
InitializeComponent();
}
//use x_ somewhere in code to actually change x
}

What I don't understand is this works for Controls but it does not work for other variables. Now suppose I passed x as an int ref, there is no way I can pass the ref itself to x_? In the case of the Controls I don't even have to use ref which confuses me as to how exactly this occurs... I know how to pass variables back and forth through methods and parent/owner so my question is very specific to this particular quasi-pointer. Maybe I am misunderstanding how passing a Control behaves and if this is the case how would you structure an int exactly as Control is so that when you assign an int to an int like a Control it changes the original int just as it changes the original Control.

This works. Send is selfsame to send.

    new InputBox(((Label)sender)).ShowDialog();

    Label Send;
    public InputBox(Label send)
    {
     Send=send; 
    }

I want this to work in the same way. Send is now the same as send but not identically the same.

    new InputBox(((string)sender)).ShowDialog();

    string Send;
    public InputBox(string send)
    {
     Send=send; 
    }

I know how to pass variables between classes and such but I am asking to specifically have a string behave the same way Label is behaving when it is passed. When it is passed it is passed exactly like a pointer in the sense that I can make a variable equal the same instance of that variable. Why can't I make a string equal to the same instance of that string?


Solution

  • I think, the immutability of the strings in .NET is a thing, that confuses you.

    The string is a reference type.
    But it designed to be immutable.

    This means, that you can't modify instances of System.String. Every time you're doing any operation, that should modify string, it just creates a new instance of string. Look at this sample:

    class A
    {
        private string someString;
    
        public A(string someString)
        {
            this.someString = someString;
        }
    
        public string SomeString
        {
            get { return someString; }
        }
    
        public void DoSomething()
        {
            someString = someString + "_abc";
        }
    }
    
    
    var sampleString = "Hello, world!";
    var a = new A(sampleString);
    
    Console.WriteLine(a.SomeString == sampleString); // prints 'true'
    
    a.DoSomething();
    
    Console.WriteLine(a.SomeString == sampleString); // prints 'false'
    Console.WriteLine(sampleString); // prints 'Hello, world!'
    Console.WriteLine(a.SomeString); // prints 'Hello, world!_abc'
    

    Initially sampleString and A.someString are equal.

    But after this line: someString = someString + "_abc" the field A.someString references another instance of string, because + operator has created a new instance, and assignment operator has assigned that instance to A.someString.

    System.String can't behave like Label, because Label is mutable. Hence, Label.Text = "Foobar"; doesn't create a new instance of label.

    UPD. If you want a mutable string, it already presents in FCL. This is StringBuilder class.