Question

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?

Was it helpful?

Solution 2

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.

OTHER TIPS

I think what you need to understand is the difference between Value Types and Reference Types

Value Types

A data type is a value type if it holds the data within its own memory allocation.

They include types of

  • All numeric data types
  • Boolean, Char, and Date
  • All structures, even if their members are reference types
  • Enumerations, since their underlying type is always SByte, Short, Integer, Long, Byte, UShort, UInteger, or ULong

whereas

Reference Types

A reference type contains a pointer to another memory location that holds the data.

they include types of

  • String
  • All arrays, even if their elements are value types
  • Class types, such as Form
  • Delegates

So further from ref (C# Reference)

The ref keyword causes an argument to be passed by reference, not by value. The effect of passing by reference is that any change to the parameter in the method is reflected in the underlying argument variable in the calling method.

That explains why you need to change the method signiture to use ref if you wish to have the changes to a value type propogate to the collung method.

Here is an example regarding the constructor calls

Control c1 = null;
Class1 cl1 = new Class1(c1); //c1 is still null after this call
Control c2 = null;
Class1 cl2 = new Class1(ref c2); //c2 is NOT null after this call

class Class1
{
    public Class1(Control c)
    {
        c = new Control();
    }

    public Class1(ref Control c)
    {
        c = new Control();
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top