出于好奇,我想在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
目前我所缺少的语言中的任何构造都可以执行此操作,而无需创建新的自定义函数或扩展方法。
答案 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}的比较