ref为变量而不是函数中的参数

时间:2011-02-07 10:02:26

标签: c# ref

假设我有一个Person类并且具有以下内容:

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

有没有办法可以更改它,这样如果我将新Person分配给BB = new Person("Harry")A也会引用相同的实例?我知道你可以在函数的ref参数赋值中做到这一点。

3 个答案:

答案 0 :(得分:36)

您想要的功能称为“ref locals”,C#不支持。

CLR确实支持生成包含ref locals的代码,几年前我写了一个C#的实验版,它具有你想要的功能,只是为了看看它是否可行。你可以这样做:

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

然后如你所说,对“b”的更改会改变“a”的内容。这两个变量成为同一存储位置的别名。

虽然这是一个很好的小功能并且运行良好,但我们决定不把它用于C#。它可能仍然会出现在假设的未来版本的语言中,但我不会对它的期望感到兴奋;它可能不会发生。

(请记住,Eric对所有Microsoft产品的假设未来版本的所有思考都只适用于娱乐目的。)

答案 1 :(得分:4)

不可能在安全代码中(超出ref函数参数)。在不安全的代码中,您可能可以使用指针来实现这一点,但我认为这不是一个好主意。

A包含对“Tom”的引用作为值。您需要引用A来更改其指向的位置。

如果我们在显式使用指针的语言中考虑类似的代码,而不是隐式地将类的实例视为引用:

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

所以你需要一个指向指针的指针才能改变A。如果将其传输到C#,则需要引用局部变量。这些仅以ref函数参数的形式提供。这避免了一些生命周期问题,因为对局部变量的引用不能安全地超过该局部变量。

如果这些不是私有变量,则可以使B成为在setter中修改A的属性。

Person B{get{return A;} set{A=value;}}

答案 2 :(得分:2)

没有直接的方法可以做到这一点。

您可以采用源代码方法,如:

A = B = new Person("Harry")

或使用通用类型。类似的东西:

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

在C#中你也可以使用一个指针(所以基本上是一个ref类型)但是这种方法不是静态可验证的,也没有建议。