如何在扩展方法中实现C#shuffle算法?

时间:2013-11-19 15:16:42

标签: c#

我有一个如下所示的列表:

IList<TQBase> hs;

public class TQBase
{
    public int i { get; set; }
    public int q { get; set; }
}

我想将这个列表洗牌,我找到了这个方法:

public static void Shuffle<T>(this IList<T> list)  
{  
    Random rng = new Random();  
    int n = list.Count;  
    while (n > 1) {  
        n--;  
        int k = rng.Next(n + 1);  
        T value = list[k];  
        list[k] = list[n];  
        list[n] = value;  
    }  
}

我试图像这样使用它:

 IList<TQBase> tqhb // This is populated from the repository in an earlier statement

 var abc = tqhb.Shuffle<TQBase>();

它给了我一个错误,指向abc并说:

 Cannot assign void to an implicitly-typed local variable   

我试图洗牌的方式有问题吗?

4 个答案:

答案 0 :(得分:1)

一种非常简单的洗牌方式:

hs.OrderBy(a => Guid.NewGuid()).ToList();

为了简单的改组,Guid足够随机。通过它为每个条目和订单创建Guid,它最终将作为随机列表。

我意识到它并没有解决你的扩展中的问题,但是其他人已经覆盖了它。看起来你正在寻找一种洗牌机制而不是特别针对这种机制,所以我提供了一种易于使用的替代方案。

答案 1 :(得分:1)

当您的扩展方法返回类型void时,您尝试为新变量赋值。像这样使用它:

tqhb.Shuffle<TQBase>();

答案 2 :(得分:1)

扩展方法将内联列表重新排列,您不必将返回值分配给任何内容(因此返回类型为void的原因!)。

tqhb.Shuffle<TQBase>();

此外,编译器应该足够聪明,可以找出方法的泛型类型,这样你就可以调用

tqhb.Shuffle();

答案 3 :(得分:1)

您的Extension方法出错:

public static IList<T> Shuffle<T>(this IList<T> list)  
{  
    Random rng = new Random();  
    int n = list.Count;  
    while (n > 1) {  
        n--;  
        int k = rng.Next(n + 1);  
        T value = list[k];  
        list[k] = list[n];  
        list[n] = value;  
    } 
    return list; 
}

或者,您在没有作业的情况下使用它:

tqhb.Shuffle<TQBase>();

tqhb之后会有所不同。