无法将IList转换为List

时间:2015-09-21 20:31:07

标签: c#

我发现这个方法可以改变一个列表,但我想要的是它返回新列表,我似乎无法弄清楚这是如何完成的。

这是我试过的

public static class Lists {

    private static System.Random rng = new System.Random();

    public static List<T> Shuffle<T>(this IList<T> list) {
        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;
    }
}

它的意思是:

  

无法将IList转换为List

我想要的是该方法返回新的Shuffled列表,但我无法让它返回列表。怎么办呢?

5 个答案:

答案 0 :(得分:3)

IList不一定是List。您的方法返回List,但会传递IList

public static List<T> Shuffle<T>(this IList<T> list) {
        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; //Still an IList!
    }

最简单/最好的解决方案是返回IList<T>而不是List<T>

public static IList<T> Shuffle<T>(this IList<T> list) {

如果确实需要实际列表,请致电ToList

return list.ToList(); //Now its a list

当然,这会比你需要的时间再次列举你的收藏。

答案 1 :(得分:1)

  

无法将List转换为IList

那是因为您有一个IList<T>并且您正在返回List<T>。您可以投射return (List<T>)list;,但如果使用其他IList<T>调用此内容,则会失败。

如果IList<T>是只读的话,它也会失败。

然而,

  

我想要的是它返回新列表

嗯,这里没有新的清单。但我们很容易就是这样:

public static List<T> Shuffle<T>(this IList<T> source) {
  List<T> list = new List<T>(source);

通过此更改,它现在会创建一个新列表,并在返回之前对其进行随机播放。

但是等等,为什么要将自己限制为IList<T>作为输入?我们可以从任何IEnumerable<T>创建一个新列表,为什么不这样做呢?

public static List<T> Shuffle<T>(this IEnumerable<T> source) {
  List<T> list = new List<T>(source);

但是,有一个缺陷是Random以非线程安全的方式用于非单线程代码。这也很容易改变,删除静态Random并具有:

public static List<T> Shuffle<T>(this IEnumerable<T> source) {
  List<T> list = new List<T>(source);
  Random rng = new System.Random();

现在它没有错误,根据需要返回一个新的List,接受更广泛的输入,并且是线程安全的。

答案 2 :(得分:1)

首先,任何List都自动为IListList必须实现IList接口上定义的方法,因此根据定义,IListIList

但是您的代码被定义为接收IList作为输入。这意味着您可以将任何实现List接口的内容传递给它。因此,您可以将DictionarySortedList或ComboBoxListItems集合或IList或任何实现List的集合类型对象传递给它。因为你正在尝试&#34;当你没有被List传递时,操纵并返回一个List,编译器正在寻找它是否可以将你传递给IList的内容转换为然后抱怨它可以&# 39;吨。实现IList的大多数对象无法自动转换为List。

您的代码令人困惑,因为您传入的输入参数是List,但名为 列表 。你应该解决这个问题。如果你想返回一个.ToList(),你需要在你的方法中从传入的任何集合类型中创建一个。这就是public static class Lists { private static System.Random rng = new System.Random(); public static List<T> Shuffle<T>(this IList<T> iList) { var list = iList.ToList(); 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; } } 的用途。

IEnumerable<T>

但更好的是,您可能应该将输入参数键入IList<T>,而不是public static class Lists { private static System.Random rng = new System.Random(); public static List<T> Shuffle<T>(this IEnumerable<T> tEnumeration) { var list = tEnumeration.ToList(); 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; } } 。您可以在任何枚举上执行ToList(),这样就可以在更广泛的潜在类型上使用您的方法。

LoginTable

答案 3 :(得分:0)

public static class Lists
{
    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;
    }
}
  • 我已将其更改为IList作为返回类型
  • 我已将<{1}}实例移到方法中。这都是关于范围的,除非另外一种方法也需要获得随机数,然后就不需要在方法之外了
  • 将开口支架移动到新线上。这不是Java。

答案 4 :(得分:-1)

  

我想要的是返回新Shuffled列表的方法,但是我不能让它返回列表。怎么办呢?

这不是您的代码所做的。你的代码将列表移动到位;它不会创建一个新的。

您可以像这样返回一个新的列表:

public static List<T> Shuffle<T>(this IList<T> list) {
    return list.OrderBy(x => rng.Next()).ToList();
}

如果您确实想要对列表进行随机播放,则应该对参数和返回类型使用相同的类型。在您的情况下,由于您未使用List特定内容,因此您应该使用IList

// Notice the I               
public static IList<T> Shuffle<T>(this IList<T> list) {
    // your code
}