17

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.

Jeff Mercado
  • 129,526
  • 32
  • 251
  • 272
Aperture
  • 2,387
  • 4
  • 25
  • 47

3 Answers3

36

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.)

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
  • Is there any use for this? I can't think of any at the moment except if we want to confuse readers... – configurator Mar 26 '11 at 21:49
  • 7
    @configurator: Some algorithms become easier to write if you can make an alias to a variable and change which variable it refers to. And there are also scenarios where you can increase the speed of certain performance-sensitive code. – Eric Lippert Mar 26 '11 at 23:41
  • 1
    @EricLippert the newest version of c# supports this feature if I'm not wrong. – Zer0 Sep 04 '19 at 11:02
  • @Zer0: Thanks for the note; I will update the text. – Eric Lippert Sep 04 '19 at 16:43
4

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;}}
CodesInChaos
  • 106,488
  • 23
  • 218
  • 262
  • Just as a note: C# DOES support pointers VERY similar to your sample. They are just not widely used (as I wrote in my answer). – Foxfire Feb 07 '11 at 10:19
  • Yes C# it does support pointers in some limited contexts. But it doesn't use an explicit notation for references/pointers in this context. If you declare `Person` as a class variables of its type are implicitly treated as a pointer/reference. – CodesInChaos Feb 07 '11 at 10:23
2

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.

Foxfire
  • 5,675
  • 21
  • 29