C#:Swap 方法的良好/最佳实现

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/552731/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 07:53:09  来源:igfitidea点击:

C#: Good/best implementation of Swap method

c#sortingshuffle

提问by Svish

I read this post about card shufflingand in many shuffling and sorting algorithms you need to swap two items in a list or array. But what does a good and efficient Swap method look like?

我读过这篇关于卡片洗牌的文章,在许多洗牌和排序算法中,您需要交换列表或数组中的两个项目。但是一个好的和高效的 Swap 方法是什么样的呢?

Let's say for a T[]and for a List<T>. How would you best implement a method that swaps two items in those two?

让我们说 for aT[]和 for a List<T>。您将如何最好地实现一种方法来交换这两个项目中的两个项目?

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

采纳答案by Marc Gravell

Well, the code you have posted (ref cards[n]) can only work with an array (not a list) - but you would use simply (where fooand barare the two values):

好吧,您发布的代码 ( ref cards[n]) 只能与数组(而不是列表)一起使用 - 但您可以简单地使用(其中foobar是两个值):

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

Or possibly (if you want atomic):

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

Interlocked.Exchange(ref foo, ref bar);
Interlocked.Exchange(ref foo, ref bar);

Personally, I don't think I'd bother with a swap method, though - just do it directly; this means that you can use (either for a list or for an array):

就我个人而言,我不认为我会费心使用交换方法 - 直接执行即可;这意味着您可以使用(用于列表或数组):

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

If you really wanted to write a swap method that worked on either a list oran array, you'd have to do something like:

如果您真的想编写一个对列表数组有效的交换方法,您必须执行以下操作:

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

(it would be trivial to make this generic) - however, the original "inline" version (i.e. not a method) working on an array will be faster.

(使这个通用化是微不足道的) - 但是,在数组上工作的原始“内联”版本(即不是方法)会更快。

回答by dirkgently

A good swap is one where you don't swap the contents. In C/C++ this would be akin to swapping pointers instead of swapping the contents. This style of swapping is fast and comes with some exception guarantee. Unfortunately, my C# is too rusty to allow me to put it in code. For simple data types, this style doesn't give you much. But once you are used to, and have to deal with larger (and more complicated) objects, it can save your life.

好的交换是不交换内容的交换。在 C/C++ 中,这类似于交换指针而不是交换内容。这种交换方式很快,并带有一些异常保证。不幸的是,我的 C# 太生疏了,无法将其放入代码中。对于简单的数据类型,这种风格不会给你太多。但是一旦您习惯了并且不得不处理更大(更复杂)的对象,它就可以挽救您的生命。

回答by Joe

Use:

用:

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

I did not realize I was in the C# section. This is C++ code, but it should have the same basic idea. I believe ^ is XOR in C# as well. It looks like instead of &you may need "ref"(?). I am not sure.

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

回答by LoxLox

What about this? It's a generic implementation of a swap method. The Jit will create a compiled version ONLY for you closed types so you don't have to worry about perfomances!

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

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

HTH Lorenzo

HTH洛伦佐

回答by Tuukka Lindroos

For anyone wondering, swapping can also be done also with Extension methods (.NET 3.0 and newer).

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

In general there seems not to be possibility to say that extension methods "this" value is ref, so you need to return it and override the old value.

一般来说,似乎不可能说扩展方法的“this”值是 ref,因此您需要返回它并覆盖旧值。

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

This extension method can be then used like this:

然后可以像这样使用此扩展方法:

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

回答by gaggleweed

11 years later and we have tuples...

11 年后,我们有了元组……

(foo, bar) = (bar, foo);