引用直接对象实例,而不是数组的单元格c#

时间:2010-12-17 20:14:50

标签: c# arrays object reference

我有对象数组(假设类名是Snap)Snap。

有没有办法保存变量直接引用单元格中的对象,而不是单元格? 因为,当我这样做时:

Snap[] goo = new Snap[3];
// here we add some objects to this array

Snap foo = (Snap)goo[1];

所以现在,如果我改变foo,那么我也会改变goo [1]。好。但现在我将在goo上做一些排列:

first i had: 0 1 2
after permutation: 1 0 2

foo仍然是goo [1]但不是这个对象!这个对象现在在goo [0]! 那么,如何直接“捕捉”这个对象,而不是单元格! 有什么想法吗?

3 个答案:

答案 0 :(得分:6)

foo 的值是对象的直接引用......但goo[1]也是如此。它们引用相同的对象,因此如果你改变了对象(不管你做了什么),那么这些改变都将通过两个引用来看到。

请注意,通过 foo更改值实际上并未更改foo。我喜欢从房屋(作为对象),街道地址(作为参考)和纸张(作为变量)的角度来考虑它。假设我把我的地址写在两张纸上,然后给你一个,给别人一个(弗雷德)。然后你把我的房子涂成红色,然后弗雷德来参观(通过阅读写在纸上的地址)。你改变了我家的颜色 - 但你根本没有改变弗雷德的那张纸。

如果你想避免这种别名,你应该考虑使你的类型不可变,并提供创建新对象的方法,这些对象就像旧对象一样,除了一些特定的变化 - 比如String那样做,例如

答案 1 :(得分:2)

没有直接(安全)方法来创建对.NET数组中元素的“地址”之类的引用。但是,您可以使用委托而不是引用,并编写类似:

的内容
Snap[] goo = new Snap[3];
Func<Snap> foo = () => (Snap)goo[1];

现在,foo是一个可以评估的函数,用于获取索引处的对象。您可以像这样使用它:

foo().SomeSnapProperty = 10;

如果您现在对goo个对象进行排列,然后再次运行上述语句,它将在索引1处为您提供新对象(因此您将修改另一个Snap

答案 2 :(得分:1)

你错过了这一点。

Snap[] goo = new Snap[3];

goo声明为对Snap实例的引用数组。也就是说,goo的每个元素都是引用,而不是Snap实例

Snap foo = goo[1];

现在,您已将foo声明为对Snap实例的引用,它恰好指的是与Snap相同的goo[1]实例

  

所以现在,如果我改变foo,那么我也会改变goo [1]。

更准确地说,如果您更改foo引用的实例,它也会更改goo[1]引用的实例(因为它们都指向同一个实例)。

  

但现在我将在goo上做一些排列

这意味着您要更改每个元素引用的Snap实例。由于您从未告诉foo也更改它所引用的Snap实例,当然它仍然引用它最初引用的相同实例。