我有两个IEnumerable<T>的实例(具有相同的T)。我想要一个IEnumerable<T>的新实例,这是两者的连接。

在。net中有内置的方法来做这个吗?还是我必须自己写?


当前回答

基于craig1231的答案,我创建了一些扩展方法…

    public static IEnumerable<T> JoinLists<T>(this IEnumerable<T> list1, IEnumerable<T> list2)
    {
        var joined = new[] { list1, list2 }.Where(x => x != null).SelectMany(x => x);
        return joined ?? Enumerable.Empty<T>();
    }
    public static IEnumerable<T> JoinLists<T>(this IEnumerable<T> list1, IEnumerable<T> list2, IEnumerable<T> list3)
    {
        var joined = new[] { list1, list2, list3 }.Where(x => x != null).SelectMany(x => x);
        return joined ?? Enumerable.Empty<T>();
    }
    public static IEnumerable<T> JoinMany<T>(params IEnumerable<T>[] array)
    {
        var final = array.Where(x => x != null).SelectMany(x => x);
        return final ?? Enumerable.Empty<T>();
    }

其他回答

是的,LINQ to Objects通过Enumerable支持这一点。合并多个数组:

var together = first.Concat(second);

注意:如果第一或第二是空的,你会收到一个ArgumentNullException。为了避免这种情况&像对待空集一样对待空值,可以像这样使用空合并操作符:

var together = (first ?? Enumerable.Empty<string>()).Concat(second ?? Enumerable.Empty<string>()); //amending `<string>` to the appropriate type

基于craig1231的答案,我创建了一些扩展方法…

    public static IEnumerable<T> JoinLists<T>(this IEnumerable<T> list1, IEnumerable<T> list2)
    {
        var joined = new[] { list1, list2 }.Where(x => x != null).SelectMany(x => x);
        return joined ?? Enumerable.Empty<T>();
    }
    public static IEnumerable<T> JoinLists<T>(this IEnumerable<T> list1, IEnumerable<T> list2, IEnumerable<T> list3)
    {
        var joined = new[] { list1, list2, list3 }.Where(x => x != null).SelectMany(x => x);
        return joined ?? Enumerable.Empty<T>();
    }
    public static IEnumerable<T> JoinMany<T>(params IEnumerable<T>[] array)
    {
        var final = array.Where(x => x != null).SelectMany(x => x);
        return final ?? Enumerable.Empty<T>();
    }

The Concat method will return an object which implements IEnumerable<T> by returning an object (call it Cat) whose enumerator will attempt to use the two passed-in enumerable items (call them A and B) in sequence. If the passed-in enumerables represent sequences which will not change during the lifetime of Cat, and which can be read from without side-effects, then Cat may be used directly. Otherwise, it may be a good idea to call ToList() on Cat and use the resulting List<T> (which will represent a snapshot of the contents of A and B).

一些枚举对象在枚举开始时获取快照,如果在枚举期间修改了集合,则将返回来自该快照的数据。如果B是这样一个可枚举对象,那么在Cat到达A的末尾之前发生的对B的任何更改都将显示在Cat的枚举中,但在此之后发生的更改将不会显示在Cat的枚举中。这样的语义可能令人困惑;给Cat拍一张快照可以避免这样的问题。

我知道这是一个相对较老的帖子,但如果你想连接多个IEnumerable,我使用以下方法

var joinedSel = new[] { first, second, third }.Where(x => x != null).SelectMany(x => x);

这消除了任何空IEnumerable,并允许多个连接。

// The answer that I was looking for when searching
public void Answer()
{
    IEnumerable<YourClass> first = this.GetFirstIEnumerableList();
    // Assign to empty list so we can use later
    IEnumerable<YourClass> second = new List<YourClass>();

    if (IwantToUseSecondList)
    {
        second = this.GetSecondIEnumerableList();  
    }
    IEnumerable<SchemapassgruppData> concatedList = first.Concat(second);
}