如何展平 List<IList>()?

How do I flatten a List<IList>()?

我有以下 属性:

public List<List<MyClass>> Items { get; set;}

这绑定到 ListViews ItemSourceIEnumerable

就是这个IEnumberableItemSource属性我现在要拉平

我已经成功地将它转换为以下内容

this.ItemsSource.Cast<IList>().ToList();

因为以下转换引发了无效转换异常:

this.ItemsSource.Cast<List<object>>().ToList();

我现在希望将此列表展平为一个直接的对象列表。我查看了 this answer: Flatten List in LINQ 并做了:

this.ItemsSource.Cast<IList>().ToList().SelectMany(x => x);

但这会产生以下错误:

'List' does not contain a definition for 'SelectMany' and no extension method 'SelectMany' accepting a first argument of type 'List' could be found (are you missing a using directive or an assembly reference?)

那我做错了什么?是否可以将 List<IList>() 展平?

额外信息:

可能值得一提的是,我正在使用 Xamarin,此代码是我的 PCL (portable class library) 的一部分,但我确定这不会是原因。

在调查这里发生的事情时,我也尝试过:

List<string> s = new List<string>();
s.SelectMany(x => x);

我收到错误:

The type arguments for method 'Enumerable.SelectMany(IEnumerable, Func>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.

先转换为正确的类型,然后就可以使用SelectMany:

var source = (List<List<MyClass>>) this.ItemsSource;
IEnumerable<MyClass> items = source.SelectMany(list => list);

随心所欲 -

var flattened = Items.SelectMany(a => a);

好的,这里很有趣。这是@TimSchmelters 回答的扩展,解释了为什么转换为正确的类型很重要

我的第二个错误是:

The type arguments for method 'Enumerable.SelectMany(IEnumerable, Func>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.

谷歌搜索后我发现 this answer to the question: "SelectMany() Cannot Infer Type Argument — Why Not?"

这说明发生此错误的原因如下:

The type returned by the delegate you pass to SelectMany must be an IEnumerable

所以错误归结为我如何投射它:

我必须将它转换为 IEnumerable<T>,显然 IList 不是那个。如果我执行以下操作,它现在可以工作了:

this.ItemsSource.Cast<IEnumerable<object>>().ToList().SelectMany(x => x);

试试这个:

this.ItemsSource.Cast<IEnumerable>().SelectMany(sublist => sublist.Cast<object>()).ToList()

我用这个示例程序测试了它,它编译了,运行:

class Test
{
    public List<List<int>> Items { get; set; }

    public IEnumerable ItemsSource { get { return this.Items; } }

    public List<object> Flatten
    {
        get { return this.ItemsSource.Cast<IEnumerable>().SelectMany(sublist => sublist.Cast<object>()).ToList(); }
    }
}

static class Program
{
    static void Main()
    {
        var t = new Test();
        t.Items = new List<List<int>>
        {
            new List<int> { 1, 2 },
            new List<int> { 11, 12 }
        };

        var r = t.Flatten;
    }
}

我假设,即使您知道项目的类型,但在使用扁平化列表时您会假装不知道...这就是为什么它 returns 对象列表而不是对象列表的原因整数