Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ref for variables not parameters in functions

Tags:

c#

ref

Suppose I have a Person class and have the following:

Person A = new Person("Tom");
Person B = A;

Is there a way I can change it so that if I assign a new Person to B, B = new Person("Harry"), A would be referring to the same instance too? I know you can do that in a ref parameter assignment in a function.

like image 463
Aperture Avatar asked Feb 07 '11 10:02

Aperture


People also ask

How do you pass the reference of a variable in a function as parameter?

Pass-by-reference means to pass the reference of an argument in the calling function to the corresponding formal parameter of the called function. The called function can modify the value of the argument by using its reference passed in. The following example shows how arguments are passed by reference.

What is the difference between ref & out parameters?

ref is used to state that the parameter passed may be modified by the method. in is used to state that the parameter passed cannot be modified by the method. out is used to state that the parameter passed must be modified by the method.

What happen passing reference type and value type as function arguments?

The value of a Value type variable is the object (or data) itself and the value of a reference type variable is a reference/pointer to the object (or data). While passing the value and reference types as parameters to a function, a copy of their values is passed to the function and not the original values.

Are parameters passed by reference?

Ref and out keywords in C# are used to pass arguments within a method or function. Both indicate that an argument/parameter is passed by reference. By default parameters are passed to a method by value. By using these keywords (ref and out) we can pass a parameter by reference.


3 Answers

UPDATE: The feature described here was added to C# 7.


The feature you want is called "ref locals" and it is not supported in C#.

The CLR does support generating code that contains ref locals, and a few years ago I wrote an experimental version of C# that had the feature you want, just to see if it would work. You could do something like:

Person a = whatever;
ref Person b = ref a;

and then as you say, changes to "b" would change the contents of "a". The two variables become aliases for the same storage location.

Though it was a nice little feature and worked well, we decided to not take it for C#. It's possible that it could still happen in a hypothetical future version of the language, but I would not get all excited about it in expectation; it will probably not happen.

(Remember, all of Eric's musings about hypothetical future versions of any Microsoft product are For Entertainment Purposes Only.)

like image 141
Eric Lippert Avatar answered Oct 14 '22 11:10

Eric Lippert


No it isn't possible in safe code(beyond ref function parameters). In unsafe code you might be able to use pointers to achieve that, but I don't think that's a good idea.

A contains the reference to "Tom" as a value. You'd need a reference to A to change where it points.

If we consider similar code in a language which explicitly uses pointers instead of implicitly treating instances of classes as references:

Person* A=new Person("Tom");
Person* B=A;
B=new Person("Harry");//Changes only B
Person** C=&A;
(*C)=new Person("John");//Now A changes

So you need a pointer to a pointer in order to change A. If you transfer this to C# you'd need a reference to a local variable. And those are only available in the form of ref function parameters. This avoids some lifetime issues since a reference to a local variable can't safely outlive that local variable.

If these are not private variables you could make B a property that modifies A in the setter.

Person B{get{return A;} set{A=value;}}
like image 31
CodesInChaos Avatar answered Oct 14 '22 10:10

CodesInChaos


There is no direct way to do that.

You can either take a source-code approach like:

A = B = new Person("Harry")

Or use a generic type. Something like:

var A = new ReferenceHolder<Person> (new Person("Tom")); 
var B = A;

In C# you could also use a pointer (so basically a ref type) but that approach is not statically verifyable and not suggested.

like image 40
Foxfire Avatar answered Oct 14 '22 12:10

Foxfire