C# - 不使用占位符交换对象

4
我被告知使用临时对象来交换数组中的元素并不是最有效的方法。
例如:
Object[] objects = new Object[10];
// -- Assign the 10 objects some values
var Temp = objects[2];
objects[2] = objects[4];
objects[4] = Temp;

不使用另一个对象,是否真的可以交换数组元素?

我知道使用数学单位可以实现,但我无法想象如何在任何其他对象类型中实现。


谁告诉你这个的?为什么他们不给你演示一下呢? - Oded
使用数字可以将两个对象“存储”在相同的元素中作为总和,但是对于通用对象则不可能。 - soandos
1
谁告诉你在C#中有更好的方法来做这件事,显然他不知道自己在说什么。 - SirViver
6个回答

7

使用临时对象进行交换是最正确的方法,比速度更重要。编写快速输出垃圾软件非常容易。

处理对象时,你无法以其他方式完成。这并不低效。指向已存在对象的额外引用变量几乎不会成为问题。

但即使对于数字值,大多数聪明的技巧在某些时候也无法产生正确的结果。


2

可能那个告诉你这件事的人是在考虑类似以下内容:

objects[2] = Interlocked.Exchange(ref objects[4], objects[2]);

当然,仅仅因为这是一行代码,并不意味着它没有使用临时变量。实际上,它使用了一个方法参数作为临时变量(对于`objects[2]`的引用被复制并传递到`Exchange`方法中),只是以这种方式隐藏起来,不太明显罢了。

1
它应该使用XCHG,这不需要中间值...尽管如果JIT生成的代码不够优化,我也不会感到惊讶。 - Yaur
无论如何,如果这个人认为这是最有效的方法,那么他比我想象中更无知。仅仅为了同步而同步(或更糟糕的是,为了“效率”而同步)并不是一个好主意。 - R. Martinho Fernandes

2

通过解构进行交换:

(first, second) = (second, first);

1

你可以使用Interlocked.Exchange来完成,但这并不比使用临时变量更快...尽管在面试之外,速度可能并不重要。


0

0
唯一需要担心创建临时对象的时间是当它非常庞大,复制对象所需的时间足够长,如果你经常这样做,例如,如果你正在对10k个项目进行排序,并将其从9999移动到1,每次测试是否应该移动或不移动,那么每次交换都会很耗费时间。然而,更有效的方法是测试所有测试并移动一次。

这里没有涉及到任何副本,除了一些引用。它们可能是32位或64位之类的东西。拥有“大型”对象并不成问题。 - R. Martinho Fernandes
当然,这并不适用于OP的例子。在C#中使用临时变量交换两个引用并不会“复制”任何东西,而只是引用本身;它不会分配新对象。 - Dan Tao
不,但是我试图给出一个不必担心的理由。 - BugFinder
这其实并不是一个“真正”的问题。这是某个人在互联网上读了一些高深的数学知识后发问的,可能他并没有理解透彻,或者想出了一种可怕的方法,在不安全的代码块中进行操作。 - Yaur

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接