如何在C#中为泛型列表类型扩展方法指定参数

5
我正在尝试创建一个扩展方法,可以对泛型列表集合进行随机排序,而不考虑其类型。但是我不确定在<..>之间应该放什么参数。我应该放object还是Type?我希望能够在任何List集合上使用此方法。
谢谢!
public static void Shuffle(this List<???????> source)
{
    Random rnd = new Random();

    for (int i = 0; i < source.Count; i++)
    {
        int index = rnd.Next(0, source.Count);
        object o = source[0];

        source.RemoveAt(0);
        source.Insert(index, o);
    }
}
4个回答

11

您需要将其变为通用方法:

public static void Shuffle<T>(this List<T> source)
{
    Random rnd = new Random();

    for (int i = 0; i < source.Count; i++)
    {
        int index = rnd.Next(0, source.Count);
        T o = source[0];

        source.RemoveAt(0);
        source.Insert(index, o);
    }
}

那将使它能够与任何 List<T> 一起工作。

4
我得学会更快地打字。无论如何,IList<T> 会更通用。 - John Saunders
当我尝试使用列出的所有方法时,我得到了以下错误信息:“参数 '2':无法将 'object' 转换为 'T'”。 - Grant
2
@Grant:你需要更改中间部分,使用“T”代替“object”(或添加转换)。正如John所提到的,使用IList<T>会更通用,尽管并非所有的IList<T>都实现插入,因此可能不适用于所有情况。 - Reed Copsey
IList<T>Insert方法。哪个类实现了IList<T>但没有实现Insert方法? - John Saunders
1
@John:任何将ICollection<T>.IsReadOnly设置为true的实现在插入时经常会抛出异常。我以前就遇到过这个问题。请参见:http://msdn.microsoft.com/en-us/library/0cfatk9t.aspx - Reed Copsey
就个人而言,我同意在IList<T>上实现这个功能更好,但这只是我想提出的一个考虑因素。 - Reed Copsey

4

您只需将自己的方法泛型化:

public static void Shuffle<T>(this List<T> source)

3
稍微有些偏题,但是使用费舍尔耶茨洗牌算法会比你的方法更加公正且性能更好:
public static void ShuffleInPlace<T>(this IList<T> source)
{
    if (source == null) throw new ArgumentNullException("source");

    var rng = new Random();

    for (int i = 0; i < source.Count - 1; i++)
    {
        int j = rng.Next(i, source.Count);

        T temp = source[j];
        source[j] = source[i];
        source[i] = temp;
    }
}

0

我认为这个解决方案处理速度更快,因为您将随机获取您的项目,并且您的集合位置将被保留以供将来使用。

namespace MyNamespace
{
    public static class MyExtensions
    {
        public static T GetRandom<T>(this List<T> source)
        {
            Random rnd = new Random();
            int index = rnd.Next(0, source.Count);
            T o = source[index];
            return o;
        }
    }
}

步骤:

  1. 创建静态类以识别您的扩展
  2. 创建您的扩展方法(必须是静态的)
  3. 处理您的数据。

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