17

假设我有一个Person班级并且有以下内容:

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

有没有办法可以更改它,以便如果我将 new 分配PersonB, B = new Person("Harry")A也会引用同一个实例?我知道您可以ref在函数的参数分配中做到这一点。

4

3 回答 3

36

更新:此处描述的功能已添加到 C# 7。


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

CLR 确实支持生成包含 ref locals 的代码,几年前我写了一个 C# 的实验版本,它具有您想要的功能,只是想看看它是否可以工作。您可以执行以下操作:

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

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

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

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

于 2011-02-07T16:35:08.740 回答
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;}}
于 2011-02-07T10:06:19.907 回答
2

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

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

A = B = new Person("Harry")

或者使用泛型类型。就像是:

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

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

于 2011-02-07T10:08:22.027 回答