ref for variables not parameters in functions

假如想象 提交于 2019-12-03 22:53:29

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

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;}}

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.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!