在linq语句中将单个项目附加到列表中

时间:2017-05-16 00:29:02

标签: c# .net

出于好奇,我想在linq流中添加一个元素,而不退出流或将单个元素转换为数组。

所以不要这样:

myEntity.SelectMany(e => e.SubEntities.Concat(new []{e})).yadayadayada

我想要一个不同的命令,我不需要将单个元素包装到数组中:

myEntity.SelectMany(e => e.SubEntities.SomeBuiltInFunc(e)).yadayadayada

myEntity.SelectMany(e => e.SubEntities.ToList().SomeBuiltInFunc(e)).yadayadayada

myEntity.SelectMany(e => SomeBuiltInFunc(e.SubEntities, e).yadayadayada

目前我所缺少的语言中的任何构造都可以执行此操作,而无需创建新的自定义函数或扩展方法。

2 个答案:

答案 0 :(得分:0)

有趣。首先,您无法向IEnumerable添加元素,因为并非所有IEnumerable都是集合。为了实现您的目标,您需要最终将IEnumerable转换为类似List的内容。

我猜你正在寻找扩展方法,这是我能想到的一种可能的解决方案:

public class Entity
{
    public IEnumerable<Entity> SubEntities { get; set; }
}

public static class EnumerableExtensions
{

    public static IEnumerable<T> SomeBuiltInFunc<T>(this IEnumerable<T> enumerable, T item)
    {
        var list = enumerable.ToList();
        list.Add(item);
        return list;
    }

}

...然后你可以这样称呼它:

IEnumerable<Entity> myEntities = new List<Entity>();
var entity = new Entity();
myEntities = myEntities.SelectMany(e => e.SubEntities.SomeBuiltInFunc(entity));

请注意我已将您的myEntity更改为myEntities,因为SelectMany()是来自IEnumerable<T>的内置扩展方法。另外,如果您需要将整个IEnumerable<T>作为参数传递给BuiltInFunc(),只需将其更改为:

public static IEnumerable<T> SomeBuiltInFunc<T>(this IEnumerable<T> enumerable, IEnumerable<T> item)
{
    var list = enumerable.ToList();
    list.AddRange(item);
    return list;
}

......然后现在:

IEnumerable<Entity> myEntities = new List<Entity>();
var entity = new Entity();
myEntities = myEntities.SelectMany(e => e.SubEntities.SomeBuiltInFunc(myEntities));

最后,更改SomeBuiltInFunc()的名称,因为它实际上并不是内置的。

我只想说明这个解决方案的问题是我们可能无法保留IEnumerable的原始具体类型。

虽然使用接口的想法根本不关心实现细节(具体类型是什么),但可能存在改变具体类型的差异。所以你要么找到解决这个问题的方法,要么小心这是否会成为你的问题。

答案 1 :(得分:0)

递归的答案非常好,我想知道Enumerable.repeat(e,1)与new [] {e}的比较