C#:Swap方法的优秀/最佳实现

我读过这篇关于卡片改组的post ,在许多改组和排序算法中,你需要在列表或数组中交换两个项目。 但是优质高效的Swap方法是什么样的呢?

让我们说一个T[]和一个List 。 您如何才能最好地实现在这两个项目中交换两个项目的方法?

 Swap(ref cards[i], ref cards[n]); // How is Swap implemented? 

那么,您发布的代码( ref cards[n] )只能使用数组(不是列表) – 但您可以简单地使用(其中foobar是两个值):

 static void Swap(ref int foo, ref int bar) { int tmp = foo; foo = bar; bar = tmp; } 

或者可能(如果你想要primefaces):

 Interlocked.Exchange(ref foo, ref bar); 

就个人而言,我不认为我会打扰交换方法 – 只是直接做; 这意味着您可以使用(对于列表或数组):

 int tmp = cards[n]; cards[n] = cards[i]; cards[i] = tmp; 

如果你真的想编写一个可以处理列表数组的交换方法,你必须做类似的事情:

 static void Swap(IList list, int indexA, int indexB) { int tmp = list[indexA]; list[indexA] = list[indexB]; list[indexB] = tmp; } 

(制作这种通用的方法很简单) – 然而,在arrays上工作的原始“内联”版本(即不是方法)会更快。

使用:

 void swap(int &a, int &b) { // &a != &b // a == b OK a ^= b; b ^= a; a ^= b; return; } 

我没有意识到我在C#部分。 这是C ++代码,但它应该具有相同的基本思想。 我相信^在C#中也是异或。 它看起来像而不是&你可能需要“ref”(?)。 我不确定。

良好的交换是指您不交换内容的交换。 在C / C ++中,这类似于交换指针而不是交换内容。 这种交换方式很快,并有一些例外保证。 不幸的是,我的C#太生锈了,不允许我把它放在代码中。 对于简单的数据类型,这种风格不会给你太多。 但是,一旦你习惯了,并且必须处理更大(更复杂)的物体,它就可以挽救你的生命。

那这个呢? 它是交换方法的通用实现。 Jit将仅为您关闭的类型创建一个编译版本,因此您不必担心性能!

 ///  /// Swap two elements /// Generic implementation by LMF ///  public static void Swap(ref T itemLeft, ref T itemRight) { T dummyItem = itemRight; itemLeft = itemRight; itemRight = dummyItem; } 

HTH Lorenzo

对于任何想知道的人来说,也可以使用Extension方法(.NET 3.0和更新版本)进行交换。

通常,似乎没有可能说扩展方法“this”值是ref,因此您需要返回它并覆盖旧值。

 public static class GeneralExtensions { public static T SwapWith(this T current, ref T other) { T tmpOther = other; other = current; return tmpOther; } } 

这个扩展方法可以像这样使用:

 int val1 = 10; int val2 = 20; val1 = val1.SwapWith(ref val2);