无法使用.ToList()将IEnumerable <int>从LINQ强制转换为List <int>?

时间:2015-11-18 06:59:08

标签: c# linq

在阅读了这个答案后https://stackoverflow.com/a/902123我想看看LINQ如何在多维列表上工作,所以这里有一些我无法正确的测试代码。

class Program
{
    static void Main(string[] args)
    {
        // Two dimensional list of ints
        var arr = new List<List<int>>();
        var rand = new Random();

        // fill the array with random values, this works fine.
        for (int i=0; i<10; i++)
        {
            arr.Add(new List<int>());
            for (int k=0; k<5; k++)
            {
                arr[i].Add( rand.Next(1, 21) );
            }
        }

        var q = from int e in arr select e;
        List<int> lst = q.ToList();  // This fails with InvalidCastException

        // here I would like to pretend that the list is one dimensional
        foreach (int i in lst)
        {
            Console.WriteLine(i);
        }
    }

我的想法是,在我将查询转换回List&lt;之后,列表应该看起来只有一个维度。 int&gt;。

可能是问题的原因:

Visual Studio告诉我&#39; q&#39;有类型

{System.Linq.Enumerable.WhereSelectEnumerableIterator< int, int >}

虽然我在这个问题的顶部链接到的答案表明&#39; q&#39;应该有类型

IEnumerable< int >

问题1 :为什么抛出异常?

问题2 :如何使用LINQ将多维度列表转换为一维列表?

谢谢。

4 个答案:

答案 0 :(得分:5)

<强> 1。为什么抛出异常?

    from e in arr select e;

而不是

    from int e in arr select e;

由于您试图将List<int>投射到int,因此抛出异常。更多linq足够聪明,可以识别变量的类型,而不是明确指定它是推荐的做法。

<强> 2。如何使用LINQ将多维度列表转换为一维列表?

在上面的情况下使用selectMany方法。

    List<int> lst = q.SelectMany(d => d).ToList();

Here是.net小提琴,供您参考。

答案 1 :(得分:2)

回答1:

我想是这样的:

var q = from int e in arr select e;

这是您的代码,您可以在其中编写一个稍后将执行的查询。

List<int> lst = q.ToList();

在此代码中,您调用查询执行,然后调用.ToList()

在这里你宣布了一个这样的声明:

var arr = new List<List<int>>();

但在查询中,您尝试将其内容List<int>转换为int,因此这就是您获得异常InvalidCastException的原因。 您的错误代码在

 var q = from int e in arr select e;

此处e是您尝试将其投放到int的列表,因此您有例外

回答2:

更改您的代码:

var q = from e in arr 
        from i in e select i;
List<int> lst = q.ToList();

答案 2 :(得分:0)

只需修改您的代码,如下所示,并检查是否按预期工作:

for (int i=0; i<10; i++)
{
     arr.Add(new List<int>());
     for (int k=0; k<5; k++)
     {
          arr[i].Add( rand.Next(1, 21) );
     }
}

//var q = from int e in arr select e; Remove this line
List<int> lst = arr.SelectMany(it=>it).ToList(); //This will flatten the result set

答案 3 :(得分:0)

在您的查询中from int e in arr select e您正试图从arg获取int值,而arg的每个值都是List<int>。这就是为什么你得到InvalidCastException因为它无法将List<int>强制转换为int的原因。如果您想从内部List<int>获取价值,可以使用查询arg.Select(list => list).Select(val => val)